When I define a dictionary which use list as key
collections.defaultdict(list)
When I print it out, it shows itself is using tuple as key.
May I know why?
import c开发者_Go百科ollections
tuple_as_dict_key = collections.defaultdict(tuple)
tuple_as_dict_key['abc', 1, 2] = 999
tuple_as_dict_key['abc', 3, 4] = 999
tuple_as_dict_key['abc', 5, 6] = 888
# defaultdict(<type 'tuple'>, {('abc', 5, 6): 888, ('abc', 1, 2): 999, ('abc', 3, 4): 999})
print tuple_as_dict_key
list_as_dict_key = collections.defaultdict(list)
list_as_dict_key['abc', 1, 2] = 999
list_as_dict_key['abc', 3, 4] = 999
list_as_dict_key['abc', 5, 6] = 888
# defaultdict(<type 'list'>, {('abc', 5, 6): 888, ('abc', 1, 2): 999, ('abc', 3, 4): 999})
# Isn't it should be defaultdict(<type 'list'>, {['abc', 5, 6]: 888, ...
print list_as_dict_key
The parameter to defaultdict
is not the type of the key, it is a function that creates default data. Your test cases don't exercise this because you're filling the dict with defined values and not using any defaults. If you were to try to get the value list_as_dict_key['abc', 7, 8]
it would return an empty list, since that is what you defined as a default value and you never set the value at that index.
When you're adding values to your dictionary you're doing it the same way in both cases and they're treated as a tuple. What you're passing to the constructor is the default value for any keys that are not present. Your default value in this case happens to be of type "type", but that has absolutely nothing to do with how other keys are treated.
There's a nice article explaining the answer to why you can't use a list as key here.
Dictionary keys can only be immutable types. Since a list is a mutable type it must be converted to an immutable type such as a tuple to be used as a dictionary key, and this conversion is being done automatically.
defaultdict
is not setting the key as a list. It's setting the default value.
>>> from collections import defaultdict
>>> d1 = collections.defaultdict(list)
>>> d1['foo']
[]
>>> d1['foo'] = 37
>>> d1['foo']
37
>>> d1['bar']
[]
>>> d1['bar'].append(37)
>>> d1['bar']
[37]
The way that you're getting a tuple as the key type is normal dict behaviour:
>>> d2 = dict()
>>> d2[37, 19, 2] = [14, 19]
>>> d2
{(37, 19, 2): [14, 19]}
The way Python works with subscripting is that a
is a
, a, b
is a tuple, a:b
is a slice object. See how it works with a list:
>>> mylist = [1, 2, 3]
>>> mylist[4, 5]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not tuple
It's taken 4, 5
as a tuple. The dict has done the same.
精彩评论