【问题标题】:Counter.most_common(n) how to override arbitrary orderingCounter.most_common(n) 如何覆盖任意排序
【发布时间】:2017-03-28 17:32:46
【问题描述】:

我可以使用 Counter.most_common() 功能完成排名/排序,从而避免这一行:d = sorted(d.items(), key=lambda x: (-x[1],x[0]), reverse=False) ??

挑战: 给您一个字符串。该字符串仅包含小写英文字母字符。您的任务是找出字符串中最常见的三个字符。

输出格式: 在单独的行上打印三个最常见的字符及其出现次数。按出现次数的降序对输出进行排序。如果出现次数相同,则按升序对字符进行排序。

在完成此操作时,我使用了 dict、Counter 和 sort 以确保“出现次数相同,按升序对字符进行排序”。内置的 Python sorted 功能确保按计数排序,然后按字母顺序排序。 我很好奇是否有办法覆盖 Counter.most_common() 默认的任意排序/顺序逻辑,因为它似乎在选择前 3 名时忽略了结果的字典顺序。

import sys
from collections import Counter

string = sys.stdin.readline().strip()
d = dict(Counter(string).most_common(3))
d = sorted(d.items(), key=lambda x: (-x[1],x[0]), reverse=False)

for letter, count in d[:3]:
    print letter, count

【问题讨论】:

标签: python python-2.7 counter


【解决方案1】:

是的doc explicitly says Counter.most_common()'s (tie-breaker) order for when counts are equal is arbitrary

  • 更新:PM2Ring 告诉我 Counter 继承了 dict 的排序。插入顺序的事情只发生在 3.6+ 中,并且只在 3.7 中得到保证。文档可能滞后。
  • 在 cPython 3.6+ 中,它们依赖于原始插入顺序(见底部),但不要依赖该实现,因为根据规范,它不是定义的行为。正如你所说,如果你想要完全确定的行为,最好自己做。
  • 我在底部展示了如何您可以像您展示的那样使用自己的排序功能monkey-patchCounter.most_common,但这是不受欢迎的。 (您编写的代码可能会意外依赖它,因此在未修补时会中断。)
  • 您可以将Counter 子类化为MyCounter,这样您就可以覆盖它的most_common。很痛苦,而且不太便携。
  • 最好的方法是编写不依赖于most_common() 的任意决胜顺序的代码和测试
  • 我同意 most_common() 不应该是硬连线的,我们应该能够将比较键或排序函数传递给 __init__()

猴子补丁Counter.most_common()

def patched_most_common(self):
    return sorted(self.items(), key=lambda x: (-x[1],x[0]))

collections.Counter.most_common = patched_most_common

collections.Counter('ccbaab')
Counter({'a': 2, 'b': 2, 'c': 2})

证明在cPython 3.7中,任意顺序是插入顺序(每个字符的第一个插入):

Counter('abccba').most_common()
[('a', 2), ('b', 2), ('c', 2)]

Counter('ccbaab').most_common()
[('c', 2), ('b', 2), ('a', 2)]

【讨论】:

  • 好答案。您不能按照current implementation 使用heapq 来降低复杂性吗?
  • @jpp:很好,我不知道 Counter 维护了一个 heapq,因此不能即时接受任意排序功能。但是我们仍然可以在以后应用我们想要的任何 O(N log N) 排序函数。
  • 是的,我想值得指出的是复杂性的增加,也就是说,这不是我们正在实施的可比更改。
  • @jpp:不,Counter 仍然可以在内部保留一个 heapq,只是我们稍后应用我们想要的任何 O(N log N) 排序函数。
  • 嗯,但我特意说的是most_common。你的猴子补丁most_common 将不再使用 heapq。还是我误解了什么?
猜你喜欢
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 2013-07-29
  • 2019-09-22
  • 1970-01-01
  • 2014-07-31
相关资源
最近更新 更多