如何计算物品的数量,但保持它们出现的顺序?

rsk*_*k82 4 python counter dictionary ordereddictionary python-3.x

例如,我需要计算一个单词出现在列表中的次数,不按频率排序,而是按单词出现的顺序排序,即插入顺序.

from collections import Counter

words = ['oranges', 'apples', 'apples', 'bananas', 'kiwis', 'kiwis', 'apples']

c = Counter(words)

print(c)
Run Code Online (Sandbox Code Playgroud)

所以代替: {'apples': 3, 'kiwis': 2, 'bananas': 1, 'oranges': 1}

我宁愿得到: {'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2}

我真的不需要这种Counter方法,任何可以产生正确结果的方法对我来说都是可以的.

Jon*_*nts 11

您可以使用配方使用collections.Countercollections.OrderedDict:

from collections import Counter, OrderedDict

class OrderedCounter(Counter, OrderedDict):
    'Counter that remembers the order elements are first encountered'

    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

    def __reduce__(self):
        return self.__class__, (OrderedDict(self),)

words = ["oranges", "apples", "apples", "bananas", "kiwis", "kiwis", "apples"]
c = OrderedCounter(words)
print(c)
# OrderedCounter(OrderedDict([('oranges', 1), ('apples', 3), ('bananas', 1), ('kiwis', 2)]))
Run Code Online (Sandbox Code Playgroud)


daw*_*awg 7

在 Python 3.6+ 上,dict现在将保持插入顺序。

所以你可以这样做:

words = ["oranges", "apples", "apples", "bananas", "kiwis", "kiwis", "apples"]
counter={}
for w in words: counter[w]=counter.get(w, 0)+1
>>> counter
{'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2}
Run Code Online (Sandbox Code Playgroud)

不幸的是,Python 3.6 和 3.7 中的 Counter 不显示它维护的插入顺序;相反,__repr__ 最常见到最不常见对返回进行排序

但是您可以使用相同的 OrderedDict配方,但只需使用 Python 3.6+ dict 代替:

from collections import Counter

class OrderedCounter(Counter, dict):
    'Counter that remembers the order elements are first encountered'
    def __repr__(self):
        return '%s(%r)' % (self.__class__.__name__, dict(self))

    def __reduce__(self):
        return self.__class__, (dict(self),)

>>> OrderedCounter(words)
OrderedCounter({'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2})
Run Code Online (Sandbox Code Playgroud)

或者,由于 Counter 是dict在 Python 3.6+ 中维护顺序的子类,您可以__repr__通过调用.items()计数器或将计数器转回 a来避免使用 Counter dict

>>> c=Counter(words)
Run Code Online (Sandbox Code Playgroud)

该 Counter 的展示按最常见元素到最少元素排序,并使用 Counters__repr__方法:

>>> c
Counter({'apples': 3, 'kiwis': 2, 'oranges': 1, 'bananas': 1})
Run Code Online (Sandbox Code Playgroud)

此演示文稿是遇到的,或插入顺序:

>>> c.items()
dict_items([('oranges', 1), ('apples', 3), ('bananas', 1), ('kiwis', 2)])
Run Code Online (Sandbox Code Playgroud)

或者,

>>> dict(c)
{'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2}
Run Code Online (Sandbox Code Playgroud)