Python - 删除字符串中重复的字母
Python - removing repeated letters in a string
假设我有一个按字母顺序排列的字符串,基于字母重复的次数。
- 示例:“BBBAADDC”。
有 3 个 B,所以它们在开头,2 个 A 和 2 个 D,所以 A 在 D 前面,因为它们按字母顺序排列,还有 1 个 C。另一个例子是 CCCCAAABBDDAB。
请注意,中间某处(即CCCC)可能有4个字母,因为可能有2对2个字母。
但是,假设我只能连续有 n 个字母。例如,如果第二个例子中的 n = 3,那么我将不得不从 4 个 C 的第一个子串中省略一个“C”,因为一行中最多只能有 3 个相同的字母。
另一个例子是字符串“CCCDDDAABC”;如果 n = 2,我将不得不删除一个 C 和一个 D 以获得字符串 CCDDAABC
示例input/output:
- n=2:输入:AAABCCCCDE,输出:AABBCCDE
- n=4:输入:EEEEFFFFGGG,输出:EEEEFFFFGGG
- n=1:输入:XXYYZZ,输出:XYZ
如何使用 Python 执行此操作?提前致谢!
这就是我现在所拥有的,虽然我不确定它是否在正确的轨道上。这里,z 是字符串的长度。
for k in range(z+1):
if final_string[k] == final_string[k+1] == final_string[k+2] == final_string[k+3]:
final_string = final_string.translate({ord(final_string[k]): None})
return final_string
这是我的解决方案:
def snip_string(string, n):
list_string = list(string)
list_string.sort()
chars = set(string)
for char in chars:
while list_string.count(char) > n:
list_string.remove(char)
return ''.join(list_string)
使用 n
的不同值调用函数会得到以下输出:
>>> string = "AAAABBBCCCDDD"
>>> snip_string(string, 1)
'ABCD'
>>> snip_string(string, 2)
'AABBCCDD'
>>> snip_string(string, 3)
'AAABBBCCCDDD'
>>>
编辑
这是我的解决方案的更新版本,如果重复字符的 组 超过 n
.
,它只会删除字符
import itertools
def snip_string(string, n):
groups = [list(g) for k, g in itertools.groupby(string)]
string_list = []
for group in groups:
while len(group) > n:
del group[-1]
string_list.extend(group)
return ''.join(string_list)
输出:
>>> string = "DDDAABBBBCCABCDE"
>>> snip_string(string, 3)
'DDDAABBBCCABCDE'
hello = "hello frrriend"
def replacing() -> str:
global hello
j = 0
for i in hello:
if j == 0:
pass
else:
if i == prev:
hello = hello.replace(i, "")
prev = i
prev = i
j += 1
return hello
replacing()
看起来有点原始,但我认为它有效,这就是我在旅途中想到的,希望它能有所帮助 :D
好的,基于, you're either pre-sorting the string or it doesn't need to be sorted by the function you're trying to create. You can do this more easily with itertools.groupby()
:
import itertools
def max_seq(text, n=1):
result = []
for k, g in itertools.groupby(text):
result.extend(list(g)[:n])
return ''.join(result)
max_seq('AAABBCCCCDE', 2)
# 'AABBCCDE'
max_seq('EEEEEFFFFGGG', 4)
# 'EEEEFFFFGGG'
max_seq('XXYYZZ')
# 'XYZ'
max_seq('CCCDDDAABC', 2)
# 'CCDDAABC'
在每个组 g
中,它被扩展然后切片直到 n
个元素([:n]
部分)所以你最多得到每个字母 n
次排。如果同一个字母出现在其他地方,则在连续计数n
时,将其视为一个独立的序列。
编辑:这是一个较短的版本,对于很长的字符串也可能表现更好。当我们使用 itertools
时,这个还使用 itertools.chain.from_iterable()
来创建扁平化的字母列表。由于它们中的每一个都是生成器,因此最后一行只有 evaluated/expanded:
import itertools
def max_seq(text, n=1):
sequences = (list(g)[:n] for _, g in itertools.groupby(text))
letters = itertools.chain.from_iterable(sequences)
return ''.join(letters)
from itertools import groupby
n = 2
def rem(string):
out = "".join(["".join(list(g)[:n]) for _, g in groupby(string)])
print(out)
这是您问题的完整代码。
s = "AABBCCDDEEE"
s2 = "AAAABBBDDDDDDD"
s3 = "CCCCAAABBDDABBB"
s4 = "AAAAAAAA"
z = "AAABBCCCCDE"
通过以下测试:
AABBCCDDEE
AABBDD
CCAABBDDABB
AA
AABBCCDE
假设我有一个按字母顺序排列的字符串,基于字母重复的次数。
- 示例:“BBBAADDC”。
有 3 个 B,所以它们在开头,2 个 A 和 2 个 D,所以 A 在 D 前面,因为它们按字母顺序排列,还有 1 个 C。另一个例子是 CCCCAAABBDDAB。
请注意,中间某处(即CCCC)可能有4个字母,因为可能有2对2个字母。
但是,假设我只能连续有 n 个字母。例如,如果第二个例子中的 n = 3,那么我将不得不从 4 个 C 的第一个子串中省略一个“C”,因为一行中最多只能有 3 个相同的字母。
另一个例子是字符串“CCCDDDAABC”;如果 n = 2,我将不得不删除一个 C 和一个 D 以获得字符串 CCDDAABC
示例input/output:
- n=2:输入:AAABCCCCDE,输出:AABBCCDE
- n=4:输入:EEEEFFFFGGG,输出:EEEEFFFFGGG
- n=1:输入:XXYYZZ,输出:XYZ
如何使用 Python 执行此操作?提前致谢!
这就是我现在所拥有的,虽然我不确定它是否在正确的轨道上。这里,z 是字符串的长度。
for k in range(z+1):
if final_string[k] == final_string[k+1] == final_string[k+2] == final_string[k+3]:
final_string = final_string.translate({ord(final_string[k]): None})
return final_string
这是我的解决方案:
def snip_string(string, n):
list_string = list(string)
list_string.sort()
chars = set(string)
for char in chars:
while list_string.count(char) > n:
list_string.remove(char)
return ''.join(list_string)
使用 n
的不同值调用函数会得到以下输出:
>>> string = "AAAABBBCCCDDD"
>>> snip_string(string, 1)
'ABCD'
>>> snip_string(string, 2)
'AABBCCDD'
>>> snip_string(string, 3)
'AAABBBCCCDDD'
>>>
编辑
这是我的解决方案的更新版本,如果重复字符的 组 超过 n
.
import itertools
def snip_string(string, n):
groups = [list(g) for k, g in itertools.groupby(string)]
string_list = []
for group in groups:
while len(group) > n:
del group[-1]
string_list.extend(group)
return ''.join(string_list)
输出:
>>> string = "DDDAABBBBCCABCDE"
>>> snip_string(string, 3)
'DDDAABBBCCABCDE'
hello = "hello frrriend"
def replacing() -> str:
global hello
j = 0
for i in hello:
if j == 0:
pass
else:
if i == prev:
hello = hello.replace(i, "")
prev = i
prev = i
j += 1
return hello
replacing()
看起来有点原始,但我认为它有效,这就是我在旅途中想到的,希望它能有所帮助 :D
好的,基于itertools.groupby()
:
import itertools
def max_seq(text, n=1):
result = []
for k, g in itertools.groupby(text):
result.extend(list(g)[:n])
return ''.join(result)
max_seq('AAABBCCCCDE', 2)
# 'AABBCCDE'
max_seq('EEEEEFFFFGGG', 4)
# 'EEEEFFFFGGG'
max_seq('XXYYZZ')
# 'XYZ'
max_seq('CCCDDDAABC', 2)
# 'CCDDAABC'
在每个组 g
中,它被扩展然后切片直到 n
个元素([:n]
部分)所以你最多得到每个字母 n
次排。如果同一个字母出现在其他地方,则在连续计数n
时,将其视为一个独立的序列。
编辑:这是一个较短的版本,对于很长的字符串也可能表现更好。当我们使用 itertools
时,这个还使用 itertools.chain.from_iterable()
来创建扁平化的字母列表。由于它们中的每一个都是生成器,因此最后一行只有 evaluated/expanded:
import itertools
def max_seq(text, n=1):
sequences = (list(g)[:n] for _, g in itertools.groupby(text))
letters = itertools.chain.from_iterable(sequences)
return ''.join(letters)
from itertools import groupby
n = 2
def rem(string):
out = "".join(["".join(list(g)[:n]) for _, g in groupby(string)])
print(out)
这是您问题的完整代码。
s = "AABBCCDDEEE"
s2 = "AAAABBBDDDDDDD"
s3 = "CCCCAAABBDDABBB"
s4 = "AAAAAAAA"
z = "AAABBCCCCDE"
通过以下测试:
AABBCCDDEE
AABBDD
CCAABBDDABB
AA
AABBCCDE