Python creating a dictionary of lists
You can use defaultdict:
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = ['1', '2']
>>> for i in a:
... for j in range(int(i), int(i) + 2):
... d[j].append(i)
...
>>> d
defaultdict(<type 'list'>, {1: ['1'], 2: ['1', '2'], 3: ['2']})
>>> d.items()
[(1, ['1']), (2, ['1', '2']), (3, ['2'])]
Python - dictionary of lists
You need to use curly rather than square brackets, but otherwise this is probably as good as it gets:
list1 = ['a', 'b', 'c']
list2 = [1, 2, 3, 4]
my_dict = {'list1': list1, 'list2': list2}
Create a dictionary from multiple lists, one list as key, other as value
Use the zip()
function to combine a list of keys with corresponding values, then pass the resulting iterator of (key, value)
combinations to dict()
:
data = {"rows": [dict(zip(key_list, row)) for row in val_list]}
This works because zip(iter1, iter2)
pairs up each element from iter1
with those of iter2
, and the dict()
constructor accepts an iterator of 2-value tuples:
Otherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects. The first object of each item becomes a key in the new dictionary, and the second object the corresponding value.
In my example above I used a list comprehension to generate the whole output list in a single expression:
>>> key_list = ['key1', 'key2', 'key3']
>>> val_list = [['v0_1', 'v0_2', 'v0_3'], ['v1_1', 'v1_2', 'v1_3'], ['v2_1', 'v2_2', 'v2_3']]
>>> {"rows": [dict(zip(key_list, row)) for row in val_list]}
{'rows': [{'key1': 'v0_1', 'key2': 'v0_2', 'key3': 'v0_3'}, {'key1': 'v1_1', 'key2': 'v1_2', 'key3': 'v1_3'}, {'key1': 'v2_1', 'key2': 'v2_2', 'key3': 'v2_3'}]}
>>> from pprint import pp
>>> pp({"rows": [dict(zip(key_list, row)) for row in val_list]})
{'rows': [{'key1': 'v0_1', 'key2': 'v0_2', 'key3': 'v0_3'},
{'key1': 'v1_1', 'key2': 'v1_2', 'key3': 'v1_3'},
{'key1': 'v2_1', 'key2': 'v2_2', 'key3': 'v2_3'}]}
dict.fromkeys()
is the wrong tool here as it reuses the second argument for each of the keys.
Create a dictionary with comprehension
Use a dict comprehension (Python 2.7 and later):
{key: value for (key, value) in iterable}
Alternatively for simpler cases or earlier version of Python, use the dict
constructor, e.g.:
pairs = [('a', 1), ('b', 2)]
dict(pairs) #=> {'a': 1, 'b': 2}
dict([(k, v+1) for k, v in pairs]) #=> {'a': 2, 'b': 3}
Given separate arrays of keys and values, use the dict
constructor with zip
:
keys = ['a', 'b']
values = [1, 2]
dict(zip(keys, values)) #=> {'a': 1, 'b': 2}
2) "zip'ped" from two separate iterables of keys/vals
dict(zip(list_of_keys, list_of_values))
How can I make a dictionary (dict) from separate lists of keys and values?
Like this:
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dictionary = dict(zip(keys, values))
print(dictionary) # {'a': 1, 'b': 2, 'c': 3}
Voila :-) The pairwise dict
constructor and zip
function are awesomely useful.
Building a dictionary with lists as values using list comprehension
Create a list of list of the values, with the first element of each sublist being the key which is [n] +
, then use that to create a dictionary.
m = [[n] + [i[1] for i in [(x%3,x) for x in range(10)]if i[0] == n] for n in range(3)]
dictt = {i[0]:i[1:] for i in m}
print(dictt)
>>> {0: [0, 3, 6, 9], 1: [1, 4, 7], 2: [2, 5, 8]}
All on one line
dictt = {i[0]:i[1:] for i in [[n] + [i[1] for i in [(x%3,x) for x in range(10)]if i[0] == n] for n in range(3)]}
Python idiom for creating dict of dict of list
It depends on what you are trying to achieve; how many keys should be added to the inner dict?
The simplest way is to just create new dict literals for the inner dict:
outerdict = {}
outerdict[name] = {type_: [v1, v2, v3]}
or you could use dict.setdefault()
to materialize the inner dict as needed:
outerdict.setdefault(name, {})[type_] = [v1, v2, v3]
or you could use collections.defaultdict()
to have it handle new values for you:
from collections import defaultdict
outerdict = defaultdict(dict)
outerdict[name][type_] = [v1, v2, v3]
When parsing a file line by line, I'd use the latter, albeit a little simplified:
from collections import defaultdict
outerdict = defaultdict(dict)
with open(filename) as infh:
for line in infh:
name, _, type_, *values = line.split()
outerdict[name][type_] = [int(i) for i in values]
This uses Python 3 syntax to capture the remaining whitespace-delimited values on the line past the first 3 into values
.
The Python 2 version would be:
with open(filename) as infh:
for line in infh:
name, _, type_, values = line.split(None, 3)
outerdict[name][type_] = map(int, values.split())
where I limited the whitespace split to just 3 splits (giving you 4 values), then splitting the values
string separately.
To have the inner-most list accumulate all values for repeated (name, type_)
key combinations, you'll need to use a slightly more complex defaultdict
setup; one that produces an inner defaultdict()
set to produce list
values:
outerdict = defaultdict(lambda: defaultdict(list))
with open(filename) as infh:
for line in infh:
name, _, type_, values = line.split(None, 3)
outerdict[name][type_].extend(map(int, values.split()))
For the file you actually posted, I'd use a different approach altogether:
import csv
from itertools import islice
outerdict = defaultdict(lambda: defaultdict(list))
with open('ImmgenCons_all_celltypes_MicroarrayExp.csv', 'rb') as infh:
reader = csv.reader(infh, skipinitialspace=True)
# first row contains metadata we need
celltypes = next(reader, [])[3:]
# next two rows can be skipped
next(islice(infh, 2, 2), None)
for row in reader:
name = row[1]
for celltype, value in zip(celltypes, row[3:]):
outerdict[name][celltype].append(float(value))
Creating a dictionary with list of lists in Python
Try using a slice:
inlinkDict[docid] = adoc[1:]
This will give you an empty list instead of a 0 for the case where only the key value is on the line. To get a 0 instead, use an or
(which always returns one of the operands):
inlinkDict[docid] = adoc[1:] or 0
Easier way with a dict comprehension:
>>> with open('/tmp/spam.txt') as f:
... data = [line.split() for line in f]
...
>>> {d[0]: d[1:] for d in data}
{'A': ['B', 'C', 'D'], 'C': ['A', 'B', 'D'], 'B': ['E', 'F'], 'D': []}
>>> {d[0]: ' '.join(d[1:]) if d[1:] else 0 for d in data}
{'A': 'B C D', 'C': 'A B D', 'B': 'E F', 'D': 0}
Note: dict keys must be unique, so if you have, say, two lines beginning with 'C' the first one will be over-written.
Related Topics
Index N Dimensional Array with (N-1) D Array
What Can You Use Generator Functions For
How to Get List of Methods in a Python Class
Simple Way to Encode a String According to a Password
Differences Between Staticfiles_Dir, Static_Root and Media_Root
Threading in a Pyqt Application: Use Qt Threads or Python Threads
Too Many Values to Unpack', Iterating Over a Dict. Key=>String, Value=>List
Appending the Same String to a List of Strings in Python
Lag When Win.Blit() Background Pygame
How to Convert the Background Color of Image to Match the Color of Pygame Window
Why Python Recursive Function Returns None