This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
syntax to insert one list into another list in python
How could be the syntax for creating a dictionary into another dictionary in python
You can declare a dictionary inside a dictionary by nesting the {} containers:
d = {'dict1': {'foo': 1, 'bar': 2}, 'dict2': {'baz': 3, 'quux': 4}}
And then you can access the elements using the [] syntax:
print d['dict1'] # {'foo': 1, 'bar': 2}
print d['dict1']['foo'] # 1
print d['dict2']['quux'] # 4
Given the above, if you want to add another dictionary to the dictionary, it can be done like so:
d['dict3'] = {'spam': 5, 'ham': 6}
or if you prefer to add items to the internal dictionary one by one:
d['dict4'] = {}
d['dict4']['king'] = 7
d['dict4']['queen'] = 8
dict1 = {}
dict1['dict2'] = {}
print dict1
>>> {'dict2': {},}
this is commonly known as nesting iterators into other iterators I think
Do you want to insert one dictionary into the other, as one of its elements, or do you want to reference the values of one dictionary from the keys of another?
Previous answers have already covered the first case, where you are creating a dictionary within another dictionary.
To re-reference the values of one dictionary into another, you can use dict.update:
>>> d1 = {1: [1]}
>>> d2 = {2: [2]}
>>> d1.update(d2)
>>> d1
{1: [1], 2: [2]}
A change to a value that's present in both dictionaries will be visible in both:
>>> d1[2].append('appended')
>>> d1
{1: [1], 2: [2, 'appended']}
>>> d2
{2: [2, 'appended']}
This is the same as copying the value over or making a new dictionary with it, i.e.
>>> d3 = {1: d1[1]}
>>> d3[1].append('appended from d3')
>>> d1[1]
[1, 'appended from d3']
Related
I have two or more dictionary, I like to merge it as one with retaining multiple values of the same key as list. I would not able to share the original code, so please help me with the following example.
Input:
a= {'a':1, 'b': 2}
b= {'aa':4, 'b': 6}
c= {'aa':3, 'c': 8}
Output:
c= {'a':1,'aa':[3,4],'b': [2,6], 'c': 8}
I suggest you read up on the defaultdict: it lets you provide a factory method that initializes missing keys, i.e. if a key is looked up but not found, it creates a value by calling factory_method(missing_key). See this example, it might make things clearer:
from collections import defaultdict
a = {'a': 1, 'b': 2}
b = {'aa': 4, 'b': 6}
c = {'aa': 3, 'c': 8}
stuff = [a, b, c]
# our factory method is the list-constructor `list`,
# so whenever we look up a value that doesn't exist, a list is created;
# we can always be sure that we have list-values
store = defaultdict(list)
for s in stuff:
for k, v in s.items():
# since we know that our value is always a list, we can safely append
store[k].append(v)
print(store)
This has the "downside" of creating one-element lists for single occurences of values, but maybe you are able to work around that.
Please find below to resolve your issue. I hope this would work for you.
from collections import defaultdict
a = {'a':1, 'b': 2}
b = {'aa':4, 'b': 6}
c={'aa':3, 'c': 8}
dd = defaultdict(list)
for d in (a,b,c):
for key, value in d.items():
dd[key].append(value)
print(dd)
Use defaultdict to automatically create a dictionary entry with an empty list.
To process all source dictionaries in a single loop, use itertools.chain.
The main loop just adds a value from the current item, to the list under
the current key.
As you wrote, for cases when under some key there is only one item,
you have to generate a work dictionary (using dictonary comprehension),
limited to items with value (list) containing only one item.
The value of such item shoud contain only the first (and only) number
from the source list.
Then use this dictionary to update d.
So the whole script can be surprisingly short, as below:
from collections import defaultdict
from itertools import chain
a = {'a':1, 'b': 2}
b = {'aa':4, 'b': 6}
c = {'aa':3, 'c': 8}
d = defaultdict(list)
for k, v in chain(a.items(), b.items(), c.items()):
d[k].append(v)
d.update({ k: v[0] for k, v in d.items() if len(v) == 1 })
As you can see, the actual processing code is contained in only 4 (last) lines.
If you print d, the result is:
defaultdict(list, {'a': 1, 'b': [2, 6], 'aa': [4, 3], 'c': 8})
This question already has answers here:
switching keys and values in a dictionary in python [duplicate]
(10 answers)
Closed 6 years ago.
I am currently preparing for a python exam and one topic we are expected to understand is having to flip a dictionary in which values become the keys and the keys become values. I am confused as to what this asking and if someone could provide me with a basic example to see what it looks like I would greatly appreciate it.
Simply write a dict comprehension expression and make it's key as value and values as key. For example:
>>> my_dict = {1: 2, 3: 4, 5: 6}
>>> {value: key for key, value in my_dict.items()}
{2: 1, 4: 3, 6: 5}
Note: Since, dict contains unique keys. In case you have same element as value for multiple keys in your original dict, you will loose related entries. For example:
# Same values v v
>>> my_dict = {1: 2, 3: 4, 5: 2}
>>> {value: key for key, value in my_dict.items()}
{2: 5, 4: 3}
#^ Only one entry of `2` as key
I'm new to python and I have become stuck on a data type issue.
I have a script which looks a bit like this
dd = defaultdict(list)
for i in arr:
dd[color].append(i)
which creates a default dict which resembles something along the lines of
dd = [('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
However I need to now access the first list([2,4]). I have tried
print(dd[0])
but this game me the following output
[][][]
I know the defaultdict has data in it as I have printed it in its entirety. However other than access the first item by its dictionary index I don't know how to access it. However, other than access the list by the dictionary key I don't know how to get it. However, I don't know the name of the key until I populate the dict.
I have thought about creating a list of lists rather than a defaultdict but being able to search via key is going to be really usefull for another part of the code so I would like to maintain this data structure if possible.
is there a way to grab the list by an index number or can you only do it using a key?
You can get a list of keys, pick the key by index, then access that key.
print(dd[dd.keys()[0]])
Note that a dictionary in Python is an unordered collection. This means that the order of keys is undefined. Consider the following example:
from collections import defaultdict
d = defaultdict (int)
d['a'] = 1
d['b'] = 2
d['c'] = 3
d['d'] = 4
d['e'] = 5
print (d)
My Python2 gives:
defaultdict(<type 'int'>, {'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4})
Python3 output is different by the way:
defaultdict(<class 'int'>, {'c': 3, 'b': 2, 'a': 1, 'e': 5, 'd': 4})
So, you will have to use some other means to remember the order in which you populate the dictionary. Either maintain a separate list of keys (colors) in the order you need, or use OrderedDict.
I have a python dictionary dict1 with more than 20,000 keys and I want to update it with another dictionary dict2. The dictionaries look like this:
dict1
key11=>[value11]
key12=>[value12]
...
...
keyxyz=>[value1x] //common key
...... so on
dict2
key21=>[value21]
key22=>[value22]
...
...
keyxyz=>[value2x] // common key
........ so on
If I use
dict1.update(dict2)
then the keys of dict1 which are similar to keys of dict2 will have their values overwritten by values of dict2. What I want is if a key is already present in dict1 then the value of that key in dict2 should be appended to value of dict1. So
dict1.conditionalUpdate(dict2)
should result in
dict1
key11=>[value11]
key12=>[value12]
key21=>[value21]
key22=>[value22]
...
...
keyxyz=>[value1x,value2x]
A naive method would be iterating over keys of dict2 for each key of dict1 and insert or update keys. Is there a better method? Does python support a built in data structure that supports this kind of functionality?
Use defaultdict from the collections module.
>>> from collections import defaultdict
>>> dict1 = {1:'a',2:'b',3:'c'}
>>> dict2 = {1:'hello', 4:'four', 5:'five'}
>>> my_dict = defaultdict(list)
>>> for k in dict1:
... my_dict[k].append(dict1[k])
...
>>> for k in dict2:
... my_dict[k].append(dict2[k])
...
>>> my_dict[1]
['a', 'hello']
This is actually pretty simple to do using a dict comprehension and itertools.groupby():
dict1 = {1: 1, 2: 2, 3: 3, 4: 4}
dict2 = {5: 6, 7: 8, 1: 1, 2: 2}
from itertools import groupby, chain
from operator import itemgetter
sorted_items = sorted(chain(dict1.items(), dict2.items()))
print({key: [value[1] for value in values] for key, values in groupby(sorted_items, itemgetter(0))})
Gives us:
{1: [1, 1], 2: [2, 2], 3: [3], 4: [4], 5: [6], 7: [8]}
Naturally, this creates a new dict, but if you need to update the first dict, you can do that trivially by updating with the new one. If your values are already lists, this may need some minor modification (but I presume you were doing that for the sake of the operation, in which case, there is no need).
Naturally, if you are using Python 2.x, then you will want to use dict.viewitems() or dict.iteritems() over dict.items(). If you are using a version of Python prior to dict comprehensions, then you could use dict((key , value) for ...) instead.
Another method without importing anything, just with the regular Python dictionary:
>>> dict1 = {1:'a',2:'b',3:'c'}
>>> dict2 = {1:'hello', 4:'four', 5:'five'}
>>> for k in dict2:
... dict1[k] = dict1.get(k,"") + dict2.get(k)
...
>>> dict1
{1: 'ahello', 2: 'b', 3: 'c', 4: 'four', 5: 'five'}
>>>
dict1.get(k,"") returns the value associated to k if it exists or an empty string otherwise, and then append the content of dict2.
This question already has answers here:
Python "extend" for a dictionary
(8 answers)
Closed 5 years ago.
I have two existing dictionaries, and I wish to 'append' one of them to the other. By that I mean that the key,values of the other dictionary should be made into the first dictionary. For example:
orig = {
'A': 1,
'B': 2,
'C': 3,
}
extra = {
'D': 4,
'E': 5,
}
dest = # Something here involving orig and extra
print dest
{
'A': 1,
'B': 2,
'C': 3,
'D': 4,
'E': 5
}
I think this all can be achieved through a for loop (maybe?), but is there some method of dictionaries or any other module that saves this job for me? The actual dictionaries I'm using are really big...
You can do
orig.update(extra)
or, if you don't want orig to be modified, make a copy first:
dest = dict(orig) # or orig.copy()
dest.update(extra)
Note that if extra and orig have overlapping keys, the final value will be taken from extra. For example,
>>> d1 = {1: 1, 2: 2}
>>> d2 = {2: 'ha!', 3: 3}
>>> d1.update(d2)
>>> d1
{1: 1, 2: 'ha!', 3: 3}
There are two ways to add one dictionary to another:
Update (modifies orig in place)
orig.update(extra) # Python 2.7+
orig |= extra # Python 3.9+
Merge (creates a new dictionary)
# Python 2.7+
dest = collections.ChainMap(orig, extra)
dest = {k: v for d in (orig, extra) for (k, v) in d.items()}
# Python 3
dest = {**orig, **extra}
dest = {**orig, 'D': 4, 'E': 5}
# Python 3.9+
dest = orig | extra
Caveats
Note that these operations are noncommutative. In all cases, the latter is the winner. E.g.
orig = {'A': 1, 'B': 2}
extra = {'A': 3, 'C': 3}
dest = orig | extra
# dest = {'A': 3, 'B': 2, 'C': 3}
dest = extra | orig
# dest = {'A': 1, 'B': 2, 'C': 3}
It is also important to note that only from Python 3.7 (and CPython 3.6) dicts are ordered. So, in previous versions, the order of the items in the dictionary may vary.
dict.update() looks like it will do what you want...
>> orig.update(extra)
>>> orig
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4}
>>>
Perhaps, though, you don't want to update your original dictionary, but work on a copy:
>>> dest = orig.copy()
>>> dest.update(extra)
>>> orig
{'A': 1, 'C': 3, 'B': 2}
>>> dest
{'A': 1, 'C': 3, 'B': 2, 'E': 5, 'D': 4}
Assuming that you do not want to change orig, you can either do a copy and update like the other answers, or you can create a new dictionary in one step by passing all items from both dictionaries into the dict constructor:
from itertools import chain
dest = dict(chain(orig.items(), extra.items()))
Or without itertools:
dest = dict(list(orig.items()) + list(extra.items()))
Note that you only need to pass the result of items() into list() on Python 3, on 2.x dict.items() already returns a list so you can just do dict(orig.items() + extra.items()).
As a more general use case, say you have a larger list of dicts that you want to combine into a single dict, you could do something like this:
from itertools import chain
dest = dict(chain.from_iterable(map(dict.items, list_of_dicts)))
A three-liner to combine or merge two dictionaries:
dest = {}
dest.update(orig)
dest.update(extra)
This creates a new dictionary dest without modifying orig and extra.
Note: If a key has different values in orig and extra, then extra overrides orig.
There is the .update() method :)
update([other])
Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None.
update() accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If
keyword arguments are specified, the dictionary is then updated with
those key/value pairs: d.update(red=1, blue=2).
Changed in version 2.4: Allowed the argument to be an iterable of key/value pairs and allowed keyword arguments.
The answer I want to give is "use collections.ChainMap", but I just discovered that it was only added in Python 3.3: https://docs.python.org/3.3/library/collections.html#chainmap-objects
You can try to crib the class from the 3.3 source though: http://hg.python.org/cpython/file/3.3/Lib/collections/init.py#l763
Here is a less feature-full Python 2.x compatible version (same author): http://code.activestate.com/recipes/305268-chained-map-lookups/
Instead of expanding/overwriting one dictionary with another using dict.merge, or creating an additional copy merging both, you create a lookup chain that searches both in order. Because it doesn't duplicate the mappings it wraps ChainMap uses very little memory, and sees later modifications to any sub-mapping. Because order matters you can also use the chain to layer defaults (i.e. user prefs > config > env).