Add new field for Python dictionary - python

I have a dict which I have used Counter to get term frequencies for each key e.g. 'A' and 'B'.
dict = {'A': Counter({'food': 30, 'menu': 19, 'good': 15}), 'B': Counter({'one': 5, 'chicken': 10})}
I would like to be able to add a new field so that each term has another value.
I have tried:
for key, values in dict.items():
for it1, it2 in values:
dict[key][it1][it2] = 0
but I receive:
ValueError: too many values to unpack (expected 2)
Do I need to remove the Counter object? How do I create a new value and how do I access this value?

You're better off creating an entirely new dictionary, to have that extra nested dict:
dct = {key: {k: {v: 0} for k, v in values.items()} for key, values in dct.items()}

I hope I understood your question. You want to add one more item to the counter?. If that is the case, you could do by updating the counter object. the count will increase as you keep on updating it.
mydict = {'A': Counter({'food': 30, 'menu': 19, 'good': 15}), 'B': Counter({'one': 5, 'chicken': 10})}
mydict['A'].update(['price'])
mydict['B'].update(['cow'])
print mydict
{'A': Counter({'food': 30, 'menu': 19, 'good': 15, 'price': 1}), 'B': Counter({'chicken': 10, 'one': 5, 'cow': 1})}
if you do update again
mydict['A'].update(['price'])
mydict['B'].update(['cow'])
print mydict
will result in
{'A': Counter({'food': 30, 'menu': 19, 'good': 15, 'price': 2}), 'B': Counter({'chicken': 10, 'one': 5, 'cow': 2})}

Without creating a new dict you can manipulate your current dict with Counter inside.
You can print your current items like this way:
dct = {'A': Counter({'food': 30, 'menu': 19, 'good': 15}), 'B': Counter({'one': 5, 'chicken': 10})}
for k, v in dct.items():
print(k, v)
Output:
>>> A Counter({'food': 30, 'menu': 19, 'good': 15})
>>> B Counter({'chicken': 10, 'one': 5})
In order to modify values inside Counter dict, you can do something like this:
for k, v in dct:
if "food" in v:
v["food"] = 666
Output:
print(dct)
>>> {'A': Counter({'food': 666, 'menu': 19, 'good': 15}), 'B': Counter({'chicken': 10, 'one': 5})}
And if you want to add new elements to your Counter dict you can do something like this:
for k, v in dct.items():
if "food" in v:
v.update({"new_food":0})
print(dct)
Output:
>>> {'A': Counter({'food': 30, 'menu': 19, 'good': 15, 'new_food': 0}), 'B': Counter({'chicken': 10, 'one': 5})}
Otherwise if you want to have a new "regular" dict you can use dict comprehension:
new_dct = {k:{key:val for key,val in v.items()} for k,v in dct.items()}
print(new_dct)
>>> {'A': {'food': 30, 'menu': 19, 'good': 15}, 'B': {'chicken': 10, 'one': 5}}

Related

Python - Update a dictionary's value with another dictionary [duplicate]

This question already has answers here:
Python Dictionary: How to update dictionary value, base on key - using separate dictionary keys
(2 answers)
Closed 1 year ago.
I have the following 2 dictionaries
a = {'a': 1, 'b': 2, 'c': 3}
b = {1: 11, 2: 22}
And I'd like to modify a into
a = {'a': 11, 'b': 22, 'c': 3}
How do I achieve this result?
You might use following dict-comprehension
a = {'a': 1, 'b': 2, 'c': 3}
b = {1: 11, 2: 22}
a = {k:b.get(v,v) for k,v in a.items()}
print(a)
output
{'a': 11, 'b': 22, 'c': 3}
Note usage of .get(v,v) so if there is not key in b original value is retained.
you can try dict comprehension
{k1: b.get(v1, v1) for k1,v1 in a.items()}
{'a': 11, 'b': 22, 'c': 3}
Try this:
a = {k: b.get(v, v) for k, v in a.items()}
try this:
a = {'a': 1, 'b': 2, 'c': 3}
b = {1: 11, 2: 22}
for k,v in a.items():
a[k] = b.get(v, v)
print(a)
Output:
{'a': 11, 'b': 22, 'c': 3}

Q: How get two value in two dictionary with same keys in python

i'm trying my code. I'm confused..How to combine these 2 dictionaries so that the value of the results is like this?
1 A 18
5 B 14
3 C 15
7 D 20
for code
d= {'A': 1, 'B': 5, 'C': 3, 'D': 7}
e= {'A': 18, 'B': 14, 'C': 15, 'D': 20}
for k,v in d.items():
print (v)
for i,(k, v) in enumerate(e.items()):
print(i,k, v)
i don't understand. Please help me. Thanks!
You can do this:
d = {'A': 1, 'B': 5, 'C': 3, 'D': 7}
e = {'A': 18, 'B': 14, 'C': 15, 'D': 20}
for k in sorted(d.keys() & e.keys()):
print(d[k], k, e[k])
The & ensures that we only use the keys present in both d and e.
Note that we need the sorted call to ensure that the dicts are indexed alphabetically in the situation where the dict keys aren't alphabetically inserted in the first place.
d= {'A': 1, 'B': 5, 'C': 3, 'D': 7}
e= {'A': 18, 'B': 14, 'C': 15, 'D': 20}
for i in d.keys():
print(d[i],i,e[i])
As the key in both dictionaries are same, so if you access one key you can easily access values from both the dictionaries and can print it in any order/format.
d= {'A': 1, 'B': 5, 'C': 3, 'D': 7}
e= {'A': 18, 'B': 14, 'C': 15, 'D': 20}
final_dictionary = {x: d.get(x, 0) + e.get(x, 0)
for x in set(d).union(e)}
print("final dictionary", str(final_dictionary))

Sorting list of nested dictionaries in python 3

I am trying to sort a dictionary containing dictionaries. Here is that dictionary:
mydict = {
'b': {'play': 2, 'scratch': 5, 'face': 8},
'c': {'do': 4, 'chew': 6},
'a': {'wash': 1, 'drink': 10, 'give': 20, 'eat': 30}
}
I want the following result after sorting:
{
'a': {'eat': 30, 'give': 20, 'drink': 10, 'wash': 1},
'b': {'face': 8, 'scratch': 5, 'play': 2},
'c': {'chew': 6, 'do': 4}
}
I will appreciate if you tell me how to solve this issue.
Creating an ordered version of mydict
Let's start with your dictionary:
>>> mydict = {
... 'b': {'play': 2, 'scratch': 5, 'face': 8},
... 'c': {'do': 4, 'chew': 6},
... 'a': {'wash': 1, 'drink': 10, 'give': 20, 'eat': 30}
... }
Ordinary dictionaries are unordered. Ordered dictionaries, however are available from the collections module:
>>> from collections import OrderedDict
We can convert your dictionary to an ordered dictionary as follows:
>>> d = OrderedDict(sorted(mydict.items()))
>>> d
OrderedDict([('a', {'give': 20, 'drink': 10, 'eat': 30, 'wash': 1}), ('b', {'scratch': 5, 'play': 2, 'face': 8}), ('c', {'do': 4, 'chew': 6})])
As you can see above, d is ordered as we want. Alternatively, we can look at just the keys and verify they are in the order that we want:
>>> d.keys()
odict_keys(['a', 'b', 'c'])
In other ways, our ordered dictionary d behaves just like a regular dictionary:
>>> d['a']
{'give': 20, 'drink': 10, 'eat': 30, 'wash': 1}
Ordering mydict by key while ordering the dictionaries inside it by value in descending order
If we want the dictionaries inside mydict to be sorted in descending order of value, we use an OrderedDict again:
>>> mydict['a']
{'give': 20, 'drink': 10, 'eat': 30, 'wash': 1}
>>> OrderedDict(sorted(mydict['a'].items(), key=lambda v: -v[-1]))
OrderedDict([('eat', 30), ('give', 20), ('drink', 10), ('wash', 1)])
If we want to apply this ordering to all entries of mydict:
>>> d = OrderedDict( sorted( (key1, OrderedDict(sorted(value.items(), key=lambda v: -v[-1]))) for (key1, value) in mydict.items()) )
>>> d
OrderedDict([('a', OrderedDict([('eat', 30), ('give', 20), ('drink', 10), ('wash', 1)])), ('b', OrderedDict([('face', 8), ('scratch', 5), ('play', 2)])), ('c', OrderedDict([('chew', 6), ('do', 4)]))])

Merge Two Dictionaries that Share Same Key:Value

I know this can be done with lists, but I'm just trying to figure out how to do this with dictionaries.
Basically, it'll go like this:
dict1 = {'a': 10, 'b': 12, 'c': 9}
dict2 = {'a': 10, 'b': 3, 'c': 9}
def intersect(dict1, dict2):
combinDict = dict()
....
print(combinDict)
{'a': 10, 'c':9}
So I only want the keys with the same value added into a new dictionary.
Any help?
You want the intersection of the items:
dict1 = {'a': 10, 'b': 12, 'c': 9}
dict2 = {'a': 10, 'b': 3, 'c': 9}
print dict(dict1.viewitems() & dict2.items())
{'a': 10, 'c': 9}
For python 3 you just want to use items:
dict(dict1.items() & dict2.items())
dict1.items() & dict2.items() returns a set of key/value pairings that are common to both dicts:
In [4]: dict1.viewitems() & dict2.items()
Out[4]: {('a', 10), ('c', 9)}
Then we simply call the dict constructor on that.
Another way to do this would be to use a dict comprehension:
In [1]: dict1 = {'a': 10, 'b': 12, 'c': 9}
In [2]: dict2 = {'a': 10, 'b': 3, 'c': 9}
In [3]: {key: dict1[key] for key in dict1 if dict1[key] == dict2.get(key)}
Out[3]: {'a': 10, 'c': 9}
This should be teeny weeny bit faster, though that wouldn't matter for regular dictionaries.

Adding the values of a dictionary to another dictionary

I'd like to add the values of a dictionary to another dictionary. For example:
adict = {1: {'a': 13, 'b': 19, 'c': 15}, 2: {'a': 7, 'b': 2, 'c': 0}}
If we add {1: {'a': 3, 'b': 9, 'c': 23}} to adict
Then adict should now be:
{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 7, 'b': 2, 'c': 0}}
If we add {3: {'a': 4}} then adict should now be:
{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 7, 'b': 2, 'c': 0}, 3: {'a': 4}}
and if we add {2: {'a': 1, 'b': 8, 'c': 27, 'd': 11}}
Then adict should now be:
{1: {'a': 16, 'b': 28, 'c': 38}, 2: {'a': 8, 'b': 10, 'c': 27, 'd': 11}, 3: {'a': 4}}
What's the best way to do this?
Simple recursive function:
>>> adict = {1: {'a': 13, 'b': 19, 'c':15}, 2: {'a': 7, 'b': 2, 'c':0}}
>>> def dict_add(a,b):
... a = a.copy()
... for k,v in b.items():
... if isinstance(v,(dict,)):
... a[k] = dict_add(a.get(k,{}),v)
... else:
... a[k] = a.get(k,0) + v
... return a
...
>>> dict_add(adict,{1: {'a': 3, 'b': 9, 'c': 23}})
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}}
>>> dict_add(dict_add(adict,{1: {'a': 3, 'b': 9, 'c': 23}}),{3:{'a':4}})
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}, 3: {'a': 4}}
This is probably very inefficient, but here's what I came up with:
def dict_add(a, b):
result = dict(a)
for key, value in b.items():
if type(value) != dict:
result[key] = result.get(key, 0) + value
else:
result[key] = dict_add(result.get(key, {}), value)
return result
Running this code results in this:
>>> adict = {1: {'a': 13, 'b': 19, 'c':15}, 2: {'a': 7, 'b': 2, 'c':0}}
>>> bdict = {1: {'a': 3, 'b': 9, 'c': 23}}
>>>
>>> print dict_add(adict, bdict)
{1: {'a': 16, 'c': 38, 'b': 28}, 2: {'a': 7, 'c': 0, 'b': 2}}
Here is a functional solution. The rec_add function does what you ask with arbitrarily nested dictionaries.
def combine(f, d1, d2):
"""Create a new dict combining d1 and d2.
Keys appearing only in one of the input dict are copied unmodified. Values
with matching keys are combined using f and copied in the output dict."""
keys = set(d1.keys() + d2.keys())
out = { }
for key in keys:
if key in d1:
if key in d2:
out[key] = f(d1[key], d2[key])
else:
out[key] = d1[key]
else:
out[key] = d2[key]
return out
def rec_combine(f, d1, d2):
"""Recursively combine all dicts."""
def aux(v1, v2):
if isinstance(v1, (dict,)) and isinstance(v2, (dict,)):
return rec_combine(f, v1, v2)
else:
return f(v1, v2)
return combine(aux, d1, d2)
def rec_add(d1, d2):
"""Recursively sum values in d1 and d2."""
return rec_combine(lambda x, y: x + y, d1, d2)

Categories

Resources