获取字符串最大出现的第一个字母

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中的默认字典行为吗?

Ble*_*der 6

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)


Min*_*ark 5

可能不是很快,但是单行!

>>> 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 timeitmost_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)