How can I turn a list of dictionaries into a single dictionary?
For example, let's say my initial list is as:
Dictionary_list = [{key:value}, {key2:value2}, {key3:value3}]
I need the resultant dictionary as:
New_dictionary = {key:value, key2:value2, key3:value3}
Another solution would be to create an empty dictionary and update it:
>>> my_list = [{'key':'value'}, {'key2':'value2'}, {'key3':'value3'}]
>>> my_dict = {}
>>> for d in my_list: my_dict.update(d)
...
>>> my_dict
{'key': 'value', 'key2': 'value2', 'key3': 'value3'}
In general, the update() method is mighty useful, typically when you want to create "environments" containing variables from successive dictionaries.
You may use dictionary comprehension to achieve this as:
>>> my_list = [{'key':'value'}, {'key2':'value2'}, {'key3':'value3'}]
>>> my_dict = {k: v for item in my_list for k, v in item.items()}
>>> my_dict
{'key3': 'value3', 'key2': 'value2', 'key': 'value'}
Note: If your initial list of dictionaries will have any "key" present in more than one dictionary, above solution will end up keeping the last "value" of "key" from the initial list.
Functional programming answer:
from functools import reduce # depending on version of python you might need this.
my_list = [{'key':'value'}, {'key2':'value2'}, {'key3':'value3'}]
def func(x,y):
x.update(y)
return x
new_dict = reduce(func, my_list)
>>> new_dict
{'key': 'value', 'key2': 'value2', 'key3': 'value3'}
One liner:
new_dict = reduce(lambda x, y: x.update(y) or x, my_list) # use side effect in lambda
Related
Lets say I have a nested dictionary
nested_dict={"dict1":{"key1":"value1", "key2":"value2", "key3":"value3;value4"}}
Now I want to split value3 and value 4 under the same key like this,
nested_dict={"dict1":{"key1":"value1", "key2":"value2", 'key3': ['value3', 'value4']}}
What would be the best way to do so in Python?
use the fact that dict is mutable and you can recursively change anything under the sun :P
nested_dict={"dict1":{"key1":"value1", "key2":"value2", "key3":"value3;value4"}}
def sol(d):
for i in d:
if type(d[i]) is dict:
sol(d[i])
else:
d[i] = d[i].split(';')
if len(d[i])==1: d[i] = d[i][0]
sol(nested_dict)
print(nested_dict)
{'dict1': {'key1': 'value1', 'key2': 'value2', 'key3': ['value3', 'value4']}}
There is a weird string representation like
"key1:value1:key2:value2:key3:value3...keyn:valuen"
I need to create a dict and it's pretty easy to solve when you have commas, however there is only colons here and you have to split the string every second colon. Code with cycle or soemthing like that looks pretty ugly, so I wonder if you could help me with oneliner.
You can just split on colons, get an iterator over the tokens and zip the iterator with itself. That will pair keys and values nicely:
s = 'key1:value1:key2:value2:key3:value3:keyn:valuen'
it = iter(s.split(':'))
dict(zip(it, it))
# {'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'keyn': 'valuen'}
If you are uncomfortable with iter (and schwobaseggls solutions wich I deem superior), you can use zipped list-slices in almost the same way:
s = 'key1:value1:key2:value2:key3:value3:keyn:valuen'
splitted = s.split(':')
# even_elements = splitted[::2] - take every 2nd starting at 0th index
# odd_elements = splitted[1::2] - take every 2nd startIng at 1st index
k = {k:v for k,v in zip(splitted[::2],splitted [1::2]) }
print(k)
Output:
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'keyn': 'valuen'}
Alternativly, you create the dict by hand:
s = 'key1:value1:key2:value2:key3:value3:keyn:valuen'
splitted = s.split(':')
d ={}
# this generates 2-slices from the list and puts them into your dict
for k,v in (splitted[i:i+2] for i in range(0,len(splitted),2)):
d[k] = v
# or d = { k:v for k, v in (splitted[i:i+2] for i in range(0,len(splitted),2) )}
# or d = dict(splitted[i:i+2] for i in range(0,len(splitted),2) )
print(d)
Output:
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'keyn': 'valuen'}
I have question about Dictionaries in Python.
here it is:
I have a dict like dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
Now i want to get all Key-Elements by the same value and save it in a new dict.
The new Dict should be look like:
new_dict = { 'b':('cdf'), 'a':('abc','gh'), 'g':('fh','hfz')}
If you are fine with lists instead of tuples in the new dictionary, you can use
from collections import defaultdict
some_dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = defaultdict(list)
for k, v in some_dict.iteritems():
new_dict[v].append(k)
If you want to avoid the use of defaultdict, you could also do
new_dict = {}
for k, v in some_dict.iteritems():
new_dict.setdefault(v, []).append(k)
Here's a naive implementation. Someone with better Python skills can probably make it more concise and awesome.
dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = {}
for pair in dict.items():
if pair[1] not in new_dict.keys():
new_dict[pair[1]] = []
new_dict[pair[1]].append(pair[0])
print new_dict
This produces
{'a': ['abc', 'gh'], 'b': ['cdf'], 'g': ['fh', 'hfz']}
If you do specifically want tuples as the values in your new dictionary, you can still use defaultdict, and use tuple concatenation. This solution works in Python 3.4+:
from collections import defaultdict
source = {'abc': 'a', 'cdf': 'b', 'gh': 'a', 'fh': 'g', 'hfz': 'g'}
target = defaultdict(tuple)
for key in source:
target[source[key]] += (key, )
print(target)
Which will produce
defaultdict(<class 'tuple'>, {'a': ('abc', 'gh'), 'g': ('fh', 'hfz'), 'b': ('cdf',)})
This will probably be slower than generating a dictionary by list insertion, and will create more objects to be collected. So, you can build your dictionary out of lists, and then map it into tuples:
target2 = defaultdict(list)
for key in source:
target2[source[key]].append(key)
for key in target2:
target2[key] = tuple(target2[key])
print(target2)
Which will give the same result as above.
It can be done this way too, without using any extra functions .
some_dict = { 'abc':'a', 'cdf':'b', 'gh':'a', 'fh':'g', 'hfz':'g' }
new_dict = { }
for keys in some_dict:
new_dict[some_dict[keys]] = [ ]
for keys in some_dict:
new_dict[some_dict[keys]].append(keys)
print(new_dict)
I have a list of 50 dictionaries and want to be sorted by a value of 'Key2' of that dictionary.
list1= [{'outside_key1': [ { 'key1': 'one', 'key2': 'xyz','key3':'three'}]} ,
{'outside_key2': [ { 'key1': 'one', 'key2': 'abc','key3':'three'}]}]
Key2 can statically be accessed by:
>>>print list1[0]['outside_key1'][0]['key2']
xyz
Now sorting based on 'key2' Like:
sorted_list = sorted(list1, key=lambda k: k[???])
Final sorted by value becomes:
[{'outside_key2': [ { 'key1': 'one', 'key2': 'abc','key3':'three'}]} ,
{'outside_key1': [ { 'key1': 'one', 'key2': 'xyz','key3':'three'}]}]
So my questions:
1. How can i dynamically access the value of 'Key2'?
2. How can i sort list of dictionary based on the value of 'Key2'?
list1= [{'outside_key1': [ { 'key1': 'one', 'key2': 'xyz','key3':'three'}]} ,
{'outside_key2': [ { 'key1': 'one', 'key2': 'abc','key3':'three'}]}]
sort_on = "key2"
decorated = [(dict_.values()[0][0][sort_on], dict_) for dict_ in list1]
decorated.sort()
result = [dict_ for (key, dict_) in decorated]
print result
dict_.values() get the outside dic values, the first [0] get the value of outside_key1, the second [0] get the first value of inner list.
Here's the fastest way to do it, as it avoids using a custom comparison function, instead using builtin comparisons. You can get more information from Sorting Lists of Dictionaries
Assuming you have only a single key for each of the dictionaries, you could do something like:
sorted(list1, key=lambda d: d[next(iter(d))][0]['key2'])
Here: d[next(iter(d))] will give the value of the first key associated with d. Of course, dictionaries are unordered, so the "first" key only has meaning when you have only a single key-value pair in the dict...
FWIW, it seems like your data-structure is really getting in the way of a clean solution here. It seems like a flat list of dict would be a better way to store the data:
list1 = [
{'key1': 'one', 'key2': 'abc', 'key3':'three'},
{ 'key1': 'one', 'key2': 'xyz','key3':'three'},
]
As having dicts with only one value and lists with only one value tend to make the container a bit overkill.
I have the following dictionary:
my_dict = {'key1': {'key2': {'foo': 'bar'} } }
and I would like to append an entry to key1->key2->key3 with value 'blah' yielding:
my_dict = {'key1': {'key2': {'foo': 'bar', 'key3': 'blah'} } }
I am looking for a generic solution that is independent of the number of keys, i.e. key1->key2->key3->key4->key5 should work as well, even though keys from key3 on downwards do not exist. So that I get:
my_dict = {'key1': {'key2': {'foo': 'bar', 'key3': {'key4': {'key5': 'blah'} } } } }
Thanks in advance.
You can use the reduce() function to traverse a series of nested dictionaries:
def get_nested(d, path):
return reduce(dict.__getitem__, path, d)
Demo:
>>> def get_nested(d, path):
... return reduce(dict.__getitem__, path, d)
...
>>> my_dict = {'key1': {'key2': {'foo': 'bar', 'key3': {'key4': {'key5': 'blah'}}}}}
>>> get_nested(my_dict, ('key1', 'key2', 'key3', 'key4', 'key5'))
'blah'
This version throws an exception when a key doesn't exist:
>>> get_nested(my_dict, ('key1', 'nonesuch'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in get_nested
KeyError: 'nonesuch'
but you could replace dict.__getitem__ with lambda d, k: d.setdefault(k, {}) to have it create empty dictionaries instead:
def get_nested_default(d, path):
return reduce(lambda d, k: d.setdefault(k, {}), path, d)
Demo:
>>> def get_nested_default(d, path):
... return reduce(lambda d, k: d.setdefault(k, {}), path, d)
...
>>> get_nested_default(my_dict, ('key1', 'nonesuch'))
{}
>>> my_dict
{'key1': {'key2': {'key3': {'key4': {'key5': 'blah'}}, 'foo': 'bar'}, 'nonesuch': {}}}
To set a value at a given path, traverse over all keys but the last one, then use the final key in a regular dictionary assignment:
def set_nested(d, path, value):
get_nested_default(d, path[:-1])[path[-1]] = value
This uses the get_nested_default() function to add empty dictionaries as needed:
>>> def set_nested(d, path, value):
... get_nested_default(d, path[:-1])[path[-1]] = value
...
>>> my_dict = {'key1': {'key2': {'foo': 'bar'}}}
>>> set_nested(my_dict, ('key1', 'key2', 'key3', 'key4', 'key5'), 'blah')
>>> my_dict
{'key1': {'key2': {'key3': {'key4': {'key5': 'blah'}}, 'foo': 'bar'}}}
An alternative to Martijn Pieters's excellent answer would be to use a nested defaultdict, rather than a regular dictionary:
from collections import defaultdict
nested = lambda: defaultdict(nested) # nested dictionary factory
my_dict = nested()
You can set values by using regular nested dictionary access semantics, and empty dictionaries will be created to fill the middle levels as necessary:
my_dict["key1"]["key2"]["key3"] = "blah"
This of course requires that the number of keys be known in advance when you write the code to set the value. If you want to be able to handle a variable-length list of keys, rather than a fixed number, you'll need functions to do the getting and setting for you, like in Martijn's answer.