Videos
I am trying to add a list, or a tuple of lists, as the value to a key inside a dictionary. I'm starting with a dictionary that has empty lists as values, and then adding to the value of each key inside a loop like this:
dict = {'key1': [], 'key2': [], 'key3': []}
list = ['a', 'b']
for key,value in dict.items():
# dict[key].append(list)
value.append(list)
print(dict)What is the difference between dict[key].append(list) and value.append(list)? They both produce the same dictionary when the other is commented out.
Further, how would I add a second list to one of these values as a tuple? Something like adding the list ['c', 'd'] to key2, like this:
{'key1': [['a', 'b']], 'key2': [['a', 'b'], ['c', 'd']], 'key3': [['a', 'b']]}Thanks for any replies!
list.append returns None, since it is an in-place operation and you are assigning it back to dates_dict[key]. So, the next time when you do dates_dict.get(key, []).append you are actually doing None.append. That is why it is failing. Instead, you can simply do
dates_dict.setdefault(key, []).append(date)
But, we have collections.defaultdict for this purpose only. You can do something like this
from collections import defaultdict
dates_dict = defaultdict(list)
for key, date in cur:
dates_dict[key].append(date)
This will create a new list object, if the key is not found in the dictionary.
Note: Since the defaultdict will create a new list if the key is not found in the dictionary, this will have unintented side-effects. For example, if you simply want to retrieve a value for the key, which is not there, it will create a new list and return it.
Is there a more elegant way to write this code?
Use collections.defaultdict:
from collections import defaultdict
dates_dict = defaultdict(list)
for key, date in cur:
dates_dict[key].append(date)
You just have to iterate the list and increment the count against the key if it is already there, otherwise set it to 1.
>>> d = {'a': 1, 'b': 2}
>>> l = ['a', 'b', 'c', 'd', 'e']
>>> for item in l:
... if item in d:
... d[item] += 1
... else:
... d[item] = 1
>>> d
{'a': 2, 'c': 1, 'b': 3, 'e': 1, 'd': 1}
You can write the same, succinctly, with dict.get, like this
>>> d = {'a': 1, 'b': 2}
>>> l = ['a', 'b', 'c', 'd', 'e']
>>> for item in l:
... d[item] = d.get(item, 0) + 1
>>> d
{'a': 2, 'c': 1, 'b': 3, 'e': 1, 'd': 1}
dict.get function will look for the key, if it is found it will return the value, otherwise it will return the value you pass in the second parameter. If the item is already a part of the dictionary, then the number against it will be returned and we add 1 to it and store it back in against the same item. If it is not found, we will get 0 (the second parameter) and we add 1 to it and store it against item.
Now, to get the total count, you can just add up all the values in the dictionary with sum function, like this
>>> sum(d.values())
8
The dict.values function will return a view of all the values in the dictionary. In our case it will numbers and we just add all of them with sum function.
Another way:
Use collections module:
>>> import collections
>>> a = {"a": 10}
>>> b = ["a", "b", "a", "1"]
>>> c = collections.Counter(b) + collections.Counter(a)
>>> c
Counter({'a': 12, '1': 1, 'b': 1})
>>> sum(c.values())
14
You are correct in that your list contains a reference to the original dictionary.
a.append(b.copy()) should do the trick.
Bear in mind that this makes a shallow copy. An alternative is to use copy.deepcopy(b), which makes a deep copy.
Also with dict
a = []
b = {1:'one'}
a.append(dict(b))
print a
b[1]='iuqsdgf'
print a
result
[{1: 'one'}]
[{1: 'one'}]
You need to append a copy, otherwise you are just adding references to the same dictionary over and over again:
yourlist.append(yourdict.copy())
I used yourdict and yourlist instead of dict and list; you don't want to mask the built-in types.
When you create the adict dictionary outside of the loop, you are appending the same dict to your alist list. It means that all the copies point to the same dictionary and you are getting the last value {1:99} every time. Just create every dictionary inside the loop and now you have your 100 different dictionaries.
alist = []
for x in range(100):
adict = {1:x}
alist.append(adict)
print(alist)