Kru*_*pös 6 python string dictionary python-3.x
我想得到一个字符串最大出现的第一个字母.
例如:
"google" -> g
"azerty" -> a
"bbbaaa" -> b
Run Code Online (Sandbox Code Playgroud)
我已经有一个工作代码,使用OrdererDict()来避免自动密钥重新排列:
from collections import OrderedDict
sentence = "google"
d = OrderedDict()
for letter in sentence:
if letter not in d.keys():
d[letter] = sentence.count(letter)
print(max(d, key=d.get)) # g
Run Code Online (Sandbox Code Playgroud)
但我正在寻找一种可能的单线或更优雅的解决方案(如果可能的话).
注意: 我已经尝试使用Counter()但它不起作用,因为python中的dict不记得键插入的顺序.
例如
from collections import Counter
sentence = "bbbaaa"
c = Counter(sentence)
print(c.most_common()[0][0]) # have 50% chances of printing 'a' rather than 'b'.
Run Code Online (Sandbox Code Playgroud)
奖金问题:有人能解释为什么OrderedDict()不是python中的默认字典行为吗?
collections.OrderedDict实际的文档有一个配方OrderedCounter:
In [5]: from collections import Counter, OrderedDict
In [6]: class OrderedCounter(Counter, OrderedDict):
...: pass
...:
In [7]: OrderedCounter("google").most_common()[0][0]
Out[7]: 'g'
Run Code Online (Sandbox Code Playgroud)
可能不是很快,但是单行!
>>> s = "aaabbbbc"
>>> sorted(s, key=lambda c: (-s.count(c), s.index(c)))[0]
'b'
Run Code Online (Sandbox Code Playgroud)
编辑
甚至更短,感谢@Ohad Eytan的评论:
>>> min(s, key=lambda c: (-s.count(c), s.index(c)))
'b'
Run Code Online (Sandbox Code Playgroud)
基准
今晚感觉很无聊,所以我对@Woohwan timeit的most_common_char()解决方案(mostcc),@ Blender的OrderedCounter解决方案(odict)和我自己的单线解决方案(onelin,使用min变体)进行了基准测试(使用).最快的解决方案始终是mostcc:对于包含少量不同字符的长字符串,比onelin快~10倍,对于非常短的字符串,比odict快4倍.对于具有少量重复字符的短字符串或字符串,onelin击败odict(否则,它是相反的).以下是详细信息(长度=字符串的长度,#chars =从每个字符中随机选择的不同unicode字符的数量,mostcc =执行10,000次mostcc的时间,odict =与mostcc相比多长的odict,onelin =与大多数人相比,线上多久了.
Length #chars mostcc odict onelin
10 10: 0.08s 3.76x 1.61x
10 100: 0.10s 3.57x 1.27x
10 1000: 0.12s 3.12x 1.34x
100 10: 0.43s 1.96x 3.29x
100 100: 0.59s 2.16x 2.18x
100 1000: 0.80s 1.92x 1.72x
1000 10: 3.48s 1.56x 9.79x
1000 100: 3.44s 1.72x 6.43x
1000 1000: 6.55s 1.68x 3.30x
Run Code Online (Sandbox Code Playgroud)