How are Counter / defaultdict ordered in Python 3.7?

柔情痞子 提交于 2019-12-04 03:10:05

问题


We know in Python 3.6 dictionaries are insertion ordered as an implementation detail, and in 3.7 insertion ordering can be relied upon.

I expected this to also be the case for subclasses of dict such as collections.Counter and collections.defaultdict. But this appears to only hold true for the defaultdict case.

So my questions are:

  1. Is it true that ordering is maintained for defaultdict but not for Counter? And, if so, is there a straightforward explanation?
  2. Should ordering of these dict subclasses in the collections module be considered implementation details? Or, for example, can we rely on defaultdict being insertion ordered like dict in Python 3.7+?

Here are my rudimentary tests:

dict: ordered

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

dict_counter = {}
for w in words:
    dict_counter[w] = dict_counter.get(w, 0)+1

print(dict_counter)

# {'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2}

Counter: unordered

from collections import Counter, defaultdict

print(Counter(words))

# Counter({'apples': 3, 'kiwis': 2, 'oranges': 1, 'bananas': 1})

defaultdict: ordered

dict_dd = defaultdict(int)
for w in words:
    dict_dd[w] += 1

print(dict_dd)

# defaultdict(<class 'int'>, {'oranges': 1, 'apples': 3, 'bananas': 1, 'kiwis': 2})

回答1:


Counter and defaultdict are both ordered now, and you can rely on it. Counter just doesn't look ordered because its repr was designed before dict ordering was guaranteed, and Counter.__repr__ sorts entries by descending order of value.

def __repr__(self):
    if not self:
        return '%s()' % self.__class__.__name__
    try:
        items = ', '.join(map('%r: %r'.__mod__, self.most_common()))
        return '%s({%s})' % (self.__class__.__name__, items)
    except TypeError:
        # handle case where values are not orderable
        return '{0}({1!r})'.format(self.__class__.__name__, dict(self))


来源:https://stackoverflow.com/questions/52174284/how-are-counter-defaultdict-ordered-in-python-3-7

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!