我如何计算 Python 中的连续字符以查看每个唯一数字在下一个唯一数字之前重复的次数?
起初,我以为我可以做这样的事情:
word = '1000'
counter = 0
print range(len(word))
for i in range(len(word) - 1):
while word[i] == word[i + 1]:
counter += 1
print counter * "0"
else:
counter = 1
print counter * "1"
这样我就可以看到每个唯一数字重复的次数。但是,当 i
达到最后一个值时,这当然会超出范围。
在上面的示例中,我希望 Python 告诉我 1 重复 1,而 0 重复 3 次。但是,由于我的 while
语句,上面的代码失败了。
我怎么能只用内置函数来做到这一点?
最佳答案
连续计数:
您可以使用 itertools.groupby
:
s = "111000222334455555"
from itertools import groupby
groups = groupby(s)
result = [(label, sum(1 for _ in group)) for label, group in groups]
之后,结果
如下所示:
[("1": 3), ("0", 3), ("2", 3), ("3", 2), ("4", 2), ("5", 5)]
你可以用这样的格式:
", ".join("{}x{}".format(label, count) for label, count in result)
# "1x3, 0x3, 2x3, 3x2, 4x2, 5x5"
总计数:
评论中有人担心你想要一个总数的数字,所以 "11100111"-> {"1":6, "0":2}
.在那种情况下,你想使用 collections.Counter
:
from collections import Counter
s = "11100111"
result = Counter(s)
# {"1":6, "0":2}
您的方法:
正如许多人所指出的,您的方法失败是因为您正在遍历 range(len(s))
但寻址 s[i+1]
。当 i
指向 s
的最后一个索引时,这会导致差一错误,因此 i+1
引发一个 索引错误
。解决此问题的一种方法是遍历 range(len(s)-1)
,但生成要迭代的内容更符合 pythonic。
对于不是绝对大的字符串,zip(s, s[1:])
不是性能问题,因此您可以这样做:
counts = []
count = 1
for a, b in zip(s, s[1:]):
if a==b:
count += 1
else:
counts.append((a, count))
count = 1
唯一的问题是,如果最后一个字符是唯一的,则您必须对其进行特殊处理。这可以用 itertools.zip_longest
修复
import itertools
counts = []
count = 1
for a, b in itertools.zip_longest(s, s[1:], fillvalue=None):
if a==b:
count += 1
else:
counts.append((a, count))
count = 1
如果您确实有一个真正巨大 的字符串并且无法忍受一次在内存中保存其中的两个,您可以使用itertools
recipe pairwise
。 .
def pairwise(iterable):
"""iterates pairwise without holding an extra copy of iterable in memory"""
a, b = itertools.tee(iterable)
next(b, None)
return itertools.zip_longest(a, b, fillvalue=None)
counts = []
count = 1
for a, b in pairwise(s):
...
关于python - 计算连续字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34443946/