How to add new values to key in a dict? - python

If I had a sample dict:
mydict = {1:{2:'A'}}
how can I add new data to key 1 so that it can be like:
mydict = {1:{2:'A'},{3:'B'}}
When I do mydict.update({3:'B'})
I get:
{1: {2: 'A'}, 3: 'B'} not {1: {2: 'A'}, {3: 'B'}}
If I try .update using the same key it just replaces the data:
mydict.update({1:{3:'B'}}) becomes
{1: {3: 'B'}}

There already have a good library for you:
from collections import defaultdict
d = defaultdict(dict)
d['person']['name']='frank'
d['person']['age']='age'
and then you can easily get the data from your 2 key! like:
print d['person']['name']

When you do mydict.update({3:'B'}) you are updating the wrong dictionary.
It looks like you want to update the dictionary in mydict[1]
This is assuming you actually want a result of {1: {2: 'A', 3: 'B'}} as your example {1: {2: 'A'}, {3: 'B'}} is not valid python.
So try mydict[1].update({3:'B'})

Simply add
mydict[1].update({3:'B'})

mydict ={2:'a',3:'b'}
d={1:mydict}
print (d)
{1: {2: 'a', 3: 'b'}}
to update more key:values you can add to mydict

Related

How to convert dict of dict to dict of specified format?

I have a dictionary of dictionaries as shown below:
d = {0: {1: ["hello"], 2: ["How are you"]}, 1: {1: ["!"], 2: ["?"]}}
and I would want it be in required format:
result = {1:["hello", "!"], 2: ["How are you", "?"]}
However, I get this in the following format using the code below:
new_d = {}
for sub in d.values():
for key, value in sub.items():
new_d.setdefault(key, []).append(value)
The result is not of required structure and it causes a list of lists.
{1: [['hello'], ['!']], 2: [['How are you'], ['?']]}
Any help here would be highly appreciated. Thanks.
use extend instead of append:
new_d.setdefault(key, []).extend(value)
The extend() method adds all the elements of an iterable (list, tuple, string etc.) to the end of the list.
If you want to solve this problem with using append() function try this code:
new_d = {}
for sub in d.values():
for key, value in sub.items():
# Control key exist...
if(key in new_d.keys()):
new_d[key].append(value[0])
else:
new_d[key] = value
You can either use .extend(value) instead of .append(value)
or you can add a basic for loop to flatten the list of all dictionary values as shown below.
new_d = {}
for sub in d.values():
for key, value in sub.items():
new_d.setdefault(key, []).extend(value)
for i in range (0,len(d)):
new_d[i+1] = [item for sublist in new_d.get(i+1) for item in sublist]
print(new_d)
The accepted answer by #Gabip correctly identifies that your only mistake was using append instead of extend.
That mistake being corrected, I'd also like to suggest a slightly different approach using dict comprehensions:
d = {0: {1: ["hello"], 2: ["How are you"]}, 1: {1: ["!"], 2: ["?"]}}
new_d = {key: d[0].get(key, []) + d[1].get(key, []) for key in d[0]}
# {1: ['hello', '!'], 2: ['How are you', '?']}
Or a more robust version that takes keys from both d[0] and d[1], in case some keys are in d[1] but not in d[0]:
d = {0: {1: ["hello"], 2: ["How are you"]}, 1: {1: ["!"], 2: ["?"], 3: ['>>>']}}
new_d = {key: d[0].get(key, []) + d[1].get(key, []) for key in set(d[0].keys()) | set(d[1].keys())}
# {1: ['hello', '!'], 2: ['How are you', '?'], 3: ['>>>']}
Finally, this wasn't explicitly part of your question, but I suggest using str.join to join the strings:
d = {0: {1: ["hello"], 2: ["How are you"]}, 1: {1: ["!"], 2: ["?"]}}
new_d = {key: ''.join(d[0].get(key, []) + d[1].get(key, [])) for key in d[0]}
# {1: 'hello!', 2: 'How are you?'}

Group list of dictionaries by value [duplicate]

This question already has answers here:
Grouping Python dictionary keys as a list and create a new dictionary with this list as a value
(2 answers)
Closed 4 years ago.
I have a list of dictionaries. How can i group that list by valaues.
list = [{a:1},{b:2},{c:1},{d:3},{e:2}]
Now my result should be like below
1:a,c
2:b,e
3:d
I tried using groupby from itertools. But i couldn't get the required result. I am using python 2.7.
Could you help me achieve this?
If you want to use groupby, the list has to be sorted by the same key you want to group by.
>>> lst = [{'a':1}, {'b':2}, {'c':1}, {'d':3}, {'e':2}]
>>> keyfunc = lambda d: next(iter(d.values()))
>>> sorted(lst, key=keyfunc)
[{'a': 1}, {'c': 1}, {'b': 2}, {'e': 2}, {'d': 3}]
>>> {k: [x for d in g for x in d]
... for k, g in itertools.groupby(sorted(lst, key=keyfunc), key=keyfunc)}
{1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']}
Here's a possible solution without using any library.
def get_dict(list):
res = {}
for elem in list:
k, v = elem.keys(), elem.values()
if v[0] in res:
res[v[0]].append(k[0])
else:
res[v[0]] = [k[0]]
return res
With a list like yours, this would output a dictionary with the following format:
{ 1:[a,c], 2:[b, e], 3:[c] }
This is considering you're always going to have the same format as input. If not, you could just adjust what is read and saved.
This might help.
list = [{"a":1},{"b":2},{"c":1},{"d":3},{"e":2}]
d = {}
for i in list:
key, value = i.items()[0]
if value not in d:
d[value] = [key]
else:
d[value].append(key)
print(d)
Output:
{1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']}
Tested in python2.7
Here is a way to do what you are looking for:
list_ = [{"a":1},{"b":2},{"c":1},{"d":3},{"e":2}]
values = set(value for dic in list_ for value in dic.values())
for value in values:
keys = [list(dic.keys())[0] for dic in list_ if value in dic.values()]
print("{}: {}".format(value, keys))
Output:
1: ['a', 'c']
2: ['b', 'e']
3: ['d']
Here's a solution that uses defaultdict.
from __future__ import print_function
from collections import defaultdict
lst = [{'a': 1}, {'b': 2}, {'c': 1}, {'d': 3}, {'e': 2}]
d = defaultdict(list)
for l in lst:
val, key = l.items()[0]
d[key].append(val)
print(d)
Output:
defaultdict(<type 'list'>, {1: ['a', 'c'], 2: ['b', 'e'], 3: ['d']})

Pythonic way of switching nested dictionary keys with nested values

In short I'm working with a nested dictionary structured like this:
nested_dict = {'key1':{'nestedkey1': 'nestedvalue1'}}
I'm trying to find a pythonic way of switching the keys with the nested values, so it would look like this:
nested_dict = {'nestedvalue1':{'nestedkey1': 'key1'}}
I'm also trying to rename the nested key values, so ultimately the dictionary would look like this:
nested_dict = {'nestedvalue1':{'NEWnestedkey1': 'key1'}}
This is closer to what I'm working with:
original_dict = {
'buford': {'id': 1},
'henley': {'id': 2},
'emi': {'id': 3},
'bronc': {'id': 4}
}
I want it to look like this:
new_dict = {
1: {'pet': 'buford'},
2: {'pet': 'henley'},
3: {'pet': 'emi'},
4: {'pet': 'bronc'}
}
Is there a way to do this in one line using a dictionary comprehension? I'm trying to get the very basics here and avoid having to use things like itertools.
You can use a dictionary comprehension to achieve this, 'swapping' things round as you build it:
new_dict = {v['id']: {'pet': k} for k, v in original_dict.items()}
To expand it to a for loop, it'd look something like:
new_dict = {}
for k, v in original_dict.items():
new_dict[v['id']] = {'pet': k}
Note that both cases obviously rely on the 'id' value being unique, or the key will be overwritten for each occurrence.
For a more generic solution, you can try this:
def replace(d, change_to = 'pet'):
return {b.values()[0]:{change_to:a} for a, b in d.items()}
Output:
{1: {'pet': 'buford'}, 2: {'pet': 'henley'}, 3: {'pet': 'emi'}, 4: {'pet': 'bronc'}}

Compact list of dictionaries into into single dictionary?

I have a list of dictionaries like the following:
l = [{0: [1L, 743.1912508784121]}, {0: [2L, 148.34440427559701]}, {0: [5L, 1275.9155165676464]}, {0: [6L, 128.46132477853394]}, {0: [8L, 1120.5549823618721]}, {0: [9L, 1000.4359061629533]}, {0: [10L, 1000.4359061629533]}, {0: [11L, 1148.2027994669606]}, {0: [12L, 222.1206974476257]}, {0: [15L, 1024.0437005257695]}, {1: [8L, 606.0185176629063]}, {1: [13L, 115.54464589045607]}, {1: [14L, 1057.134622491455]}, {1: [16L, 1000.346200460439]}, {1: [17L, 285.73897308106336]}, {2: [3L, 941.8651982485691]}, {2: [4L, 1001.6313224538114]}, {2: [7L, 1017.0693313362076]}, {2: [11L, 427.7241587977401]}]
in this specific case the list has 19 dictionaries with 3 different keys (0,1,2).
What I'm trying to do is to transform it into a single dictionary where the values of each key is made by another dictionary.
So for example, extracting 4 elements of the list, I'd like to compact this:
l = [{0: [1L, 743.1912508784121]}, {0: [2L, 148.34440427559701]}, {1: [13L, 115.54464589045607]}, {1: [14L, 1057.134622491455]}]
into:
d = {0:{1L: 743.1912508784121, 2L: 148.34440427559701}, 1:{13L: 115.54464589045607, 14L: 1057.134622491455}}
I hope I made myself clear
This'll work, hopefully the code should be fairly self-explanatory.
Note that you'll need to use dictionary.iteritems() in Python 2.x, as dictionary.items() is Python 3.x only.
d ={}
for dictionary in l:
for key, (k, v) in dictionary.items():
if key not in d:
d[key] = {}
d[key][k] = v
You may get this result using collections.defaultdict as:
from collections import defautdict
my_dict = defaultdict(dict)
for d in l:
for k, (v1, v2) in d.items():
my_dict[k][v1] = v2
where my_dict will hold the final value as:
{0: {1L: 743.1912508784121, 2L: 148.34440427559701, 5L: 1275.9155165676464, 6L: 128.46132477853394, 8L: 1120.5549823618721, 9L: 1000.4359061629533, 10L: 1000.4359061629533, 11L: 1148.2027994669606, 12L: 222.1206974476257, 15L: 1024.0437005257695}, 1: {8L: 606.0185176629063, 16L: 1000.346200460439, 13L: 115.54464589045607, 14L: 1057.134622491455, 17L: 285.73897308106336}, 2: {11L: 427.7241587977401, 3L: 941.8651982485691, 4L: 1001.6313224538114, 7L: 1017.0693313362076}}
Note: Since dict can have unique keys, it will have the value of nested dict based on the last value in the list.

Should dict store key in order by inc?

I have a dict with integers as keys. Tell me please, does a dict store data with sorted keys or not?
I wrote a little code to test (as follows):
>>>
>>> d = {1: 'a', 3: 'a'}
>>> d
{1: 'a', 3: 'a'}
>>> d[2] = 'a'
>>> d
{1: 'a', 2: 'a', 3: 'a'}
>>>
But I am not sure that this behavior is standard and works all the time.
Dictionaries in python are not sorted. Read more on dicts here:
http://docs.python.org/library/stdtypes.html?highlight=dict#dict
But you can use sorted python built-in method to sort keys:
for k in sorted(myDict):
myDict[k] # do something
Or Look here for collections.OrderedDict implementation
You can also mix sorted method and OrderedDict to use it later(sure this will only word in case you will not add new items into it - otherwise it simply better to use sorted method):
d = {1: 'a', 3: 'a'}
from collections import OrderedDict
sorted_d = OrderedDict((k, d[k]) for k in sorted(d))
A little bit more experimenting would have soon shown you that they are not sorted:
>>> d = {1: 'a', 3: 'a', 8: 'a'}
>>> d
{8: 'a', 1: 'a', 3: 'a'}
but even that is implementation dependant. Don't depend on the order at all.
The internal dict keeps no sorting order for the keys. If you want a fast C-implementation for C python have a look at sorteddict which is included in my ordereddict package for CPython:
http://anthon.home.xs4all.nl/Python/ordereddict/

Categories