我正在尝试计算列表元素中重复字母出现的次数。
例如,给定
arr = ['capps','hat','haaah']
我列出了清单,得到了['1','0','1']
def myfunc(words):
counter = 0 #counters dup letters in words
len_ = len(words)-1
for i in range(len_):
if words[i] == words[i+1]: #if the letter ahead is the same add one
counter+=1
return counter
def minimalOperations(arr):
return [*map(myfunc,arr)] #map fuc applies myfunc to element in words.
但是我的代码会输出[1,0,2]
我不确定为什么我计算过多。 谁能帮助我解决这个问题,谢谢。
答案 0 :(得分:2)
使用正则表达式的更有效解决方案:
import re
def myfunc(words):
reg_str = r"(\w)\1{1,}"
return len(re.findall(reg_str, words))
此函数将查找包含相同字母的长度为2或更大的子字符串的数量。因此,您的示例中的“ aaa”将仅被计数一次。
对于
这样的字符串'hhhhfafaahggaa'
输出将为4,因为同一字母的4个最大子字符串至少出现两次:'hhh','ss','gg','aa'
答案 1 :(得分:1)
您无需考虑连续有两个以上相同字符的情况。为此,您可以向后和往后看:
if (words[i] == words[i+1]) and (words[i] != words[i-1] if i != 0 else True)
# as before
三元语句有助于循环的第一次迭代,避免将字符串的最后一个字母与第一个字母进行比较。
另一种解决方案是使用itertools.groupby
并计算组的长度大于1的实例数。
arr = ['capps','hat','haaah']
from itertools import groupby
res = [sum(1 for _, j in groupby(el) if sum(1 for _ in j) > 1) for el in arr]
print(res)
[1, 0, 1]
sum(1 for _ in j)
部分用于计算生成器中的项目数。也可以使用len(list(j))
,尽管这需要列表构造。
答案 2 :(得分:0)
好吧,您的代码计算了重复次数,因此观察到的结果很合逻辑:
arr = ['capps','hat','haaah']
所以最终您得到了[1,0,2]。
出于您的目的,我建议您使用正则表达式来匹配并计算每个单词中重复字母的组数。我还用列表理解取代了map()
的用法,使我更容易理解:
import re
def myfunc(words):
return len(re.findall(r'(\w)\1+', words))
def minimalOperations(arr):
return [myfunc(a) for a in arr]
arr = ['capps','hat','haaah']
print(minimalOperations(arr)) # [1,0,1]
arr = ['cappsuul','hatppprrrrtyyy','haaah']
print(minimalOperations(arr)) # [2,3,1]
答案 3 :(得分:0)
您需要跟踪更多状态,特别是如果您现在正在查看重复项。
def myfunc(words):
counter = 0 #counters dup letters in words
seen = None
len_ = len(words)-1
for i in range(len_):
if words[i] == words[i+1] and words[i+1] != seen: #if the letter ahead is the same add one and wasn't the first
counter+=1
seen = words[i]
return counter
这将为您提供以下输出
>>> arr = ['capps','hat','haaah']
>>> map(myfunc, arr)
[1, 0, 1]
正如其他人指出的那样,您可以使用正则表达式和交易明晰性来提高性能。他们的关键是找到一个表示“两个或多个重复字符”的正则表达式,并且可能取决于您认为什么字符(例如,您如何处理重复的标点符号?)
注意:为此,“ regex”在技术上是正则表达式的扩展,因为它需要内存。
表格将为len(re.findall(regex, words))
答案 4 :(得分:0)
我会将这种问题分解为较小的部分。首先将重复项分组。 The documentation for itertools有针对此类情况的分组依据和食谱。
unique_justseen
的经过稍微编辑的版本看起来像这样:
duplicates = (len(sum(1 for _ in group) for _key, group in itertools.groupby("haaah")))
并产生值:1、3、1。这些值中的任何一个大于1时,您就会重复。因此,只需数一下:
sum(n > 1 for n in duplicates)
答案 5 :(得分:0)
使用re.findall
匹配2个或更多字母
>>> arr = ['capps','hat','haaah']
>>> [len(re.findall(r'(.)\1+', w)) for w in arr]
[1, 0, 1]