Consider a basic counter initialized from a mapping:
dict_1 = {'a': 1, 'b': 2, 'c': 3}
count_1 = Counter(dict_1)
print count_1
>>> Counter({'c': 3, 'b': 2, 'a': 1})
Everything makes sense. But Counter also allows me to initialize from a dictionary that has non-integers as both keys and values. For example,
dict_2 = {'a': 'apple', 'b': 'banana', 'c': 'cheese'}
count_2 = Counter(dict_2)
print count_2
>>> Counter({'c': 'cheese', 'b': 'banana', 'a': 'apple'})
The code written above is Python 2.7, but I also tested it on Python 3.5 and got the same result. This seems to violate the most basic rule of the counter, where "elements are stored as dictionary keys and their counts are stored as dictionary values." Is counter supposed to allow values that aren't integers? Shouldn't it thrown an error or something? What explains this behavior?
There are no restrictions on the values of a counter object and this is clearly stated in the documentation:
The
Counter
class itself is a dictionary subclass with no restrictions on its keys and values. The values are intended to be numbers representing counts, but you could store anything in the value field.
[Emphasis mine]
The behavior of some of the Counter
methods is also described in a general case e.g.:
The
most_common()
method requires only that the values be orderable.
>>> count_2.most_common()
[('c', 'cheese'), ('b', 'banana'), ('a', 'apple')]
>>> count_2.most_common(2)
[('c', 'cheese'), ('b', 'banana')]
So one could easily run into problems in Python 3 if you have unorderable types as values in the counter object:
>>> count_2['d'] = 2
>>> count_2
Counter({'c': 'cheese', 'a': 'apple', 'b': 'banana', 'd': 2})
>>> count_2.most_common()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Python34\lib\collections\__init__.py", line 492, in most_common
return sorted(self.items(), key=_itemgetter(1), reverse=True)
TypeError: unorderable types: str() < int()
Hence, you'll generally want to keep the values as the actual count of objects and use a vanilla dictionary when values are intended to be non numeric types or more strictly non integers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With