例如,如果给定的字符串是:
3 a, 4 b, 2 c, 1 d, 1 a, 4 e
我想说的是:
while source!="":
leading = source[0]
c=0
while source!="" and source[0]==leading:
c+=1
source=source[1:]
print(c, leading)
使用强力循环在Python中很容易做到,但我想知道是否有更多Pythonic /更清晰的单行方式。
我的蛮力:
enc_nums = [(x + y) % 27 for (x, y) in zip(nums, rk_nums)]
...
dec_nums = [(x - y) % 27 for (x, y) in zip(enc_nums, rk_nums)]
答案 0 :(得分:9)
使用Counter计算字符串中每个不同字母的数量,无论位置如何:
>>> s="aaabbbbccdaeeee"
>>> from collections import Counter
>>> Counter(s)
Counter({'a': 4, 'b': 4, 'e': 4, 'c': 2, 'd': 1})
如果字符串中的位置具有含义:
,则可以使用groupbyfrom itertools import groupby
li=[]
for k, l in groupby(s):
li.append((k, len(list(l))))
print li
打印:
[('a', 3), ('b', 4), ('c', 2), ('d', 1), ('a', 1), ('e', 4)]
可以减少到列表理解:
[(k,len(list(l))) for k, l in groupby(s)]
你甚至可以使用正则表达式:
>>> [(m.group(0)[0], len(m.group(0))) for m in re.finditer(r'((\w)\2*)', s)]
[('a', 3), ('b', 4), ('c', 2), ('d', 1), ('a', 1), ('e', 4)]
答案 1 :(得分:0)
有多种解决问题的方法。 @dawg已经发布了最好的解决方案,但是如果由于某些原因您不被允许使用Counter()
(也许是工作面试或学校任务),那么您实际上可以通过几种方式解决问题。
from collections import Counter, defaultdict
def counter_counts(s):
""" Preferred method using Counter()
Arguments:
s {string} -- [string to have each character counted]
Returns:
[dict] -- [dictionary of counts of each char]
"""
return Counter(s)
def default_counts(s):
""" Alternative solution using defaultdict
Arguments:
s {string} -- [string to have each character counted]
Returns:
[dict] -- [dictionary of counts of each char]
"""
counts = defaultdict(int) # each key is initalized to 0
for char in s:
counts[char] += 1 # increment the count of each character by 1
return counts
def vanilla_counts_1(s):
""" Alternative solution using a vanilla dicitonary
Arguments:
s {string} -- [string to have each character counted]
Returns:
[dict] -- [dictionary of counts of each char]
"""
counts = {}
for char in s:
# we have to manually check that each value is in the dictionary before attempting to increment it
if char in counts:
counts[char] += 1
else:
counts[char] = 1
return counts
def vanilla_counts_2(s):
""" Alternative solution using a vanilla dicitonary
This version uses the .get() method to increment instead of checking if a key already exists
Arguments:
s {string} -- [string to have each character counted]
Returns:
[dict] -- [dictionary of counts of each char]
"""
counts = {}
for char in s:
# the second argument in .get() is the default value if we dont find the key
counts[char] = counts.get(char, 0) + 1
return counts
为了好玩,让我们看看每种方法的执行情况。
对于s = "aaabbbbccdaeeee"
和10,000次运行:
Counter: 0.0330204963684082s
defaultdict: 0.01565241813659668s
vanilla 1: 0.01562952995300293s
vanilla 2: 0.015581130981445312s
(实际上令人惊讶的结果)
现在让我们测试一下,如果将字符串设置为《创世纪》的整个纯文本版本并运行1000次,会发生什么情况:
Counter: 8.500739336013794s
defaultdict: 14.721554040908813s
vanilla 1: 18.089043855667114s
vanilla 2: 27.01840090751648s
看起来创建Counter()
对象的开销变得不那么重要了!
(这些不是很科学的测试,但是有点有趣)。