Reputation: 369
I have two lists that I'm merging into a dictionary
keys = ['p2p', 'groupchat']
tests_available = ['p2p_1', 'p2p_2', 'p2p_3', 'groupchat_1', 'groupchat_2']
The expected output will be something like
{'p2p': ['p2p_1', 'p2p_2', 'p2p_3'], 'groupchat': ['groupchat_1', 'groupchat_2']
}
My code to create the dictionary is below.
out = {}
out = dict.fromkeys(keys)
for tests in tests_available:
if tests.split('_')[0] in keys:
key = tests.split('_')[0]
out[key].append(tests)
However, it is throwing the error 'NoneType' object has no attribute 'append' when it is trying to append the values to the key. Can anyone help me identify what is wrong in my code?
Upvotes: 0
Views: 4388
Reputation: 149776
For a small number of keys/tests a dictionary comprehension would work as well:
keys = ['p2p', 'groupchat']
tests_available = ['p2p_1', 'p2p_2', 'p2p_3', 'groupchat_1', 'groupchat_2']
out = {k: [v for v in tests_available if v.startswith(k)] for k in keys}
Demo:
>>> out
{'groupchat': ['groupchat_1', 'groupchat_2'], 'p2p': ['p2p_1', 'p2p_2', 'p2p_3']}
Upvotes: 1
Reputation: 394031
If you use a defaultdict then the append call will work as the value type defaults to a list:
In [269]:
from collections import defaultdict
keys = ['p2p', 'groupchat']
tests_available = ['p2p_1', 'p2p_2', 'p2p_3', 'groupchat_1', 'groupchat_2']
d = defaultdict(list)
for test in tests_available:
k = test.split('_')[0]
if k in keys:
d[k].append(test)
d.items()
Out[269]:
dict_items([('p2p', ['p2p_1', 'p2p_2', 'p2p_3']), ('groupchat', ['groupchat_1', 'groupchat_2'])])
See the docs: https://docs.python.org/2/library/collections.html#defaultdict-examples
Upvotes: 4
Reputation: 180401
Your values are set to None in fromkeys unless you explicitly set a value:
fromkeys(seq[, value])
Create a new dictionary with keys from seq and values set to value. fromkeys() is a class method that returns a new dictionary. value defaults to None.
In your case you need to create lists as values for each key:
d = {k:[] for k in keys}
You can also do your if check using the dict:
d = {k:[] for k in keys}
for test in tests_available:
k = tests.split('_', 1)[0]
if k in d:
d[k].append(test)
You can pass a value to use to fromkeys but it has to be immutable or you will be sharing the same object among all keys.
Upvotes: 3