打印有序计数器中的第一个键值



我正在尝试按照与 OrderedCounter 输出中显示的顺序相同的顺序打印出键值对。

from collections import Counter, OrderedDict
class OrderedCounter(Counter, OrderedDict):
    pass
c = OrderedCounter('supernatural')
print c

我得到以下输出:

OrderedCounter({'u': 2, 'r': 2, 'a': 2, 's': 1, 'p': 1, 'e': 1, 'n': 1, 't': 1, 'l': 1})

有没有办法我只能打印出第一个键,值对?

我基本上是在尝试打印给定字符串中的第一个重复字符。

问题是__repr__被第一个超类使用(因为你不覆盖它(,这是Counter .Counter的表示形式是按值降序排序。你子类OrderedDict并且sorted是稳定的这一事实使"u"看起来是第一个元素。

但是,Counter 不提供__iter__方法,因此您将使用 OrderedDict__iter__,它只是保留广告顺序:

>>> next(iter(c.items()))
('s', 1)

要获得第一个重复字符,只需使用理解:

>>> next((key, value) for key, value in c.items() if value > 1)
('u', 2)

(对于 Python2,您可能希望使用 iteritems() 而不是 items() (

若要打印第一个最常见的值,可以使用 Counter.most_common 方法:

>>> c.most_common(1)
[('u', 2)]

此任务不需要CountOrderedDict。这是一个优化的方法(对于长度n复杂度为 O(n( 的字符串(:

In [35]: def first_repeated(s):
             seen = set()
             for i, j in enumerate(s):
                if j in seen: # membership check in set is O(1)
                    return j, s.count(j, i + 1) + 2 
                seen.add(j)
   ....:         
In [36]: first_repeated(s)
Out[36]: ('u', 2)

以下是其他答案的基准测试,显示此方法快了近 4-5 倍:

In [39]: def counter_based(s):
   ....:     c = Counter(s)
   ....:     return next(key for key in c if c[key] > 1)
   ....: 
In [40]: %timeit counter_based(s)
100000 loops, best of 3: 5.09 us per loop
In [41]: %timeit first_repeated(s)
1000000 loops, best of 3: 1.71 us per loop

此外,如果您想对大量数据执行后缀树,您可以使用后缀树更快地完成此任务。这是我自己在 github 中对该算法的优化实现。如果您不熟悉此数据结构和算法 https://github.com/kasramvd/SuffixTree,也可以使用文档和有用的链接

作为在生成器表达式中使用str.counter的另一个基于线性的答案,您可以使用 @Stefan Pochmann 建议的以下方法:

next((c, s.count(c)) for c in s if s.count(c) > 1)

据我了解,我认为您正在寻找这样的东西:

print c.most_common()[0]

这提供了输出('u', 2)

如果您需要计数器,

则可以对其进行过滤和排序以获取所需的内容:

from collections import Counter
input_string = 'supernatural'
c = Counter(input_string)
print sorted((pair for pair in c.items() if pair[1]>1), key=lambda x: input_string.index(x[0]))[0]
我们

过滤计数器以仅返回多次出现的字母,根据其在输入字符串中的位置对其进行排序,并返回我们找到的第一对。因此,这打印('u', 2)

最新更新