Combining dictionaries in Python - python

I am trying to combine the following dictionaries into the ideal output and am not sure how it is done.
day1 = {'Sci': [21.0],'Math': [16.0]}
day2 = {'Sci': [11.1],'Math': [16.1]}
Expected output:
{'Sci': [21.0, 11.1],'Math': [16.0, 16.1]}
How can I go about it?

You can use dictionary comprehension:
day1 = {'Sci': [21.0],'Math': [16.0]}
day2 = {'Sci': [11.1],'Math': [16.1]}
output = {key: d1 + d2 for (key, d1), d2 in zip(day1.items(), day2.values())}
print(output)
Output:
{'Sci': [21.0, 11.1], 'Math': [16.0, 16.1]}
Assuming day1 has the same keys as day2.
Edit: if we are going to assume that, the previous method is way overcomplicated. This suffises:
output = {k: day1[k] + day2[k] for k in day1}

Based on the question, here is my attempt at solving your problem. Please keep in mind this only works if both of your dictionaries have the same keys.
day1 = {'Sci': [21.0],'Math': [16.0]}
day2 = {'Sci': [11.1],'Math': [16.1]}
output = {}
for key in day1:
output[key] = day1[key] + day2[key]
print(output)
The code above will give you the following output:
{'Sci': [21.0, 11.1], 'Math': [16.0, 16.1]}

In these cases, I like to create a generic function to simplify the task at hand.
Here is a helper function which accepts any number of input dict objects to merge the K/V pairs of:
Note: this assumes that all values in an input dict object are of type list.
def merge(*dicts):
res = {}
for d in dicts:
for k in d:
if cur_list := res.get(k):
cur_list += d[k]
else:
cur_list = d[k]
res[k] = cur_list
return res
Now, calling the function via:
day1 = {'Sci': [21.0],'Math': [16.0]}
day2 = {'Sci': [11.1],'Math': [16.1]}
print(merge(day1, day2))
Result:
{'Sci': [21.0, 11.1], 'Math': [16.0, 16.1]}

Related

is there a way to only have a value in a list if the key appears multiple times in a file?

I'm trying to make a dictionary from items in a file. What I have now works but I was wondering if there is a way to only have a list if the key is a duplicate that has different value.so, if I have this
micheal math 2
jim chem 3
jim math 3
pam cs 4
expected output:
{micheal:[math,2],jim: [[chem,3], [math,3]], pam: [cs,4]}
actual output:
{micheal:[[math,2]],jim: [[chem,3], [math,3]], pam: [[cs,4]]}
current code:
example_dict = {}
for line in dictionary:
line = (line.strip()).split(' ')
key = line[0]
if key not in example_dict
example_dict[key] = []
example_dict[key].append(line[1:])
return example_dict
With your current solution, go over your example_dict afterward and flatten values that only have one element, e.x.:
...
example_dict = {k: (v if len(v) > 1 else v[0]) for k, v in example_dict.items()}
return example_dict
It seems like it would make a lot of sense to use dictionaries instead of tuple lists as values.
example_dict = {}
for line in dictionary:
name, subject, grade = line.strip().split() # optional, but cleaner
if name not in example_dict:
example_dict[name] = {}
example_dict[name][subject] = grade
Result:
{'micheal': {'math': '2'},
'jim': {'chem': '3', 'math': '3'},
'pam': {'cs': '4'}}

python dict key in list to filter - python

a = [{"price": 1,"id": 1},{"price": 8.2, "id": 2}, {"price": 10.99,"id": 3}]
user = ['price', 'abc']
output supposed to be:
output = [{"price": 1},{"price": 8.2}, {"price": 10.99}]
The scenario is that dict a keys should be filtered by user list
You can use a set intersection operation to get the keys to retain:
result = [{k: d[k] for k in set(d.keys()).intersection(set(user))} for d in a]
print(result)
This prints:
[{'price': 1}, {'price': 8.2}, {'price': 10.99}]
You can use list comprehension
[{u: val_a.get(u) for u in user if val_a.get(u)} for val_a in a]
Nested comprehensions may not be desirable and the above example checks twice for the value. Building your results by a loop may give the most straightforward result and be readable at the same time:
results = []
for val_a in a:
result = {}
for u in user:
u_val = val_a.get(u)
if u_val:
result.update({u: u_val})
results.append(result)
Python3.8+:
results = []
for val_a in a:
result = {}
for u in user:
if u_val := val_a.get(u)
result.update({u: u_val})
results.append(result)

match values between two dictionaries, extract the keys with equals value in new dictionary

For example, I have:
dict1 = {"name":"Cristian","surname":"Rossi","nationality":"Italy","color":"red"}
dict2 = {"country":"Italy","loc":"Milan","other":"red","car":"ford"}
dictionaries is large, some thousands elements.
In this example, the values in both dictionaries are Italy and red. So, I would this result
dict3 = {"nationality":"country","color":"other"}
It may be easier to convert the dictionaries into sets?
Thanks!
Get a set of the common values in both dictionaries. Then get the keys for those values and build a dictionary.
dict1 = {"name":"Cristian","surname":"Rossi","nationality":"Italy","color":"red"}
dict2 = {"country":"Italy","loc":"Milan","other":"red","car":"ford"}
common = set(dict1.values()) & set(dict2.values())
keys1 = [k for k,v in dict1.items() if v in common]
keys2 = [k for k,v in dict2.items() if v in common]
d = {k1:k2 for k1,k2 in zip(keys1, keys2)}
print(d)
Output:
{'nationality': 'country', 'color': 'other'}
Here is one approach which first inverts the dicts and then looks at an intersection of the values. Given that intersection of values it then builds a final result with all of the keys that each value mapped to in the original dicts. Assumes Python 3.
d1 = {"name":"Cristian","surname":"Rossi","nationality":"Italy","color":"red"}
d2 = {"country":"Italy","loc":"Milan","other":"red","car":"ford"}
def inv_dict(d):
inv = {}
for k, v in d.items():
inv.setdefault(v, []).append(k)
return inv
id1 = inv_dict(d1)
id2 = inv_dict(d2)
result = {v:id1[v] + id2[v] for v in id1.keys() & id2.keys()}
print(result)
# {'Italy': ['nationality', 'country'], 'red': ['color', 'other']}
The output is slightly different than what you specified, but it's unclear how your example output would work if the same value appeared in multiple keys in one or both dicts.

Convert nested dictionary values to single string

How can I convert the below nested dictionary values to a single string ?
data = {'people': {'first': {'fname': 'P1', 'lname': 'L1'}, 'second': { 'fname': 'P2', 'lname': 'L2'}}}
Output should be P1 L1, P2 L2
Here is my current code:
print ', '.join("%s %s" % (data['people'][person].get('fname'), data['people'][person].get('lname')) for person in data['people'])
Is this a efficient way for a larger set to items in people dict ? If not how to improve this ?
You can make your expression a bit short by only looping over just values and using named field in format string(Emphasis is to keep it more readable):
>>> print ', '.join("{fname} {lname}".format(**p) for p in data['people'].values())
P2 L2, P1 L1
In Python 3.2+ this can also be done using str.format_map:
>>> print (', '.join("{fname} {lname}".format_map(p) for p in data['people'].values()))
P1 L1, P2 L2
If the keys fname or lname might be missing from the dicts then you could do something like this:
def get_values(dct, keys):
return (dct.get(k) for k in keys)
...
>>> keys = ('fname', 'lname')
>>> print ', '.join("{} {}".format(*get_values(p, keys)) for p in data['people'].values())
P2 L2, P1 L1
If number of values are huge then replace values() with itervalues(). In Python 3 use values() only.
Dicts don't have any specified order, so you cannot expect the output to be P1 L1, P2 L2 here.
Your data structure is recursive so you'll need a recursive function to obtain them
def get_values(data):
values = []
for k, v in data.items():
if isinstance(v, dict):
values.extend(get_values(v))
else:
values.append(v)
return values
result = list()
for person in data["people"]:
for val in data["people"][person].values():
result.append(val)
result.append(", ")
result.pop()
print(' '.join(result))
or
result = list()
for person in data["people"]:
result.append(data["people"][person]["fname"])
result.append(data["people"][person]["lname"])
result.append(", ")
result.pop()
print(' '.join(result))
one = data['people']['second'].values()
two = data['people']['first'].values()
three = one + two
three.reverse()
for each in three:
print each,
I hope this what you are looking for.
data = {'people': {'first': {'fname': 'P1', 'lname': 'L1'}, 'second': { 'fname': 'P2', 'lname': 'L2'}}}
def myprint(d):
for k, v in d.iteritems():
if isinstance(v, dict):
myprint(v)
else:
print "{0} : {1}".format(k, v)
myprint(data)

Python: How to construct a tuple, value dictionary from a list of key,value dictionary?

I have a list of dicts as follows:
lst = [{'unitname':'unit1', 'test1': 2, 'test2': 9}, {'unitname':'unit2', 'test1': 24, 'test2': 35}]
How do I contruct a single dict as follows:
dictA = { ('unit1','test1'): 2, ('unit1','test2'): 9, ('unit2','test1'):24, ('unit2','test2' : 35 }
`
I have all the unit names & test names in a list:
unitnames = ['unit1','unit2']
testnames = ['test1','test2']
I tried but missed out some tests for some units.
dictA = {}
for unit in unitnames:
for dict in lst:
for k,v in dict.items():
dictA[unit,k] = v
Advices? Thanks.
dict(((d['unitname'], k), t)
for d in lst
for (k, t) in d.iteritems()
if k != 'unitname')
You could try:
dictA = {}
for l in lst:
name = l.pop('unitname')
for test in l:
dictA[name, test] = l[test]
Posted at the same time and with the same assumptions as Gareth's solution - however this will not give you the extra item of (name, 'unitname') = name
Marcelo Cantos's solution is quite elegant, but would be easier for mere mortals like us to parse like this:
dict( ((d['unitname'], k), t)
for d in lst
for (k, t) in d.iteritems()
if k != 'unitname'
)
dictA = {}
for d in lst:
unit = d['unitname']
for test in testnames:
if test in d:
dictA[unit,test] = d[test]
I'm assuming (1) that all the dicts in your list have a unitname key, (2) that its value is always one of the units you're interested in, (3) that some dicts in the list may have entries for tests you aren't interested in, and (4) that some tests you're interested in may be absent from some dicts in the list. Those assumptions are a bit arbitrary; if any happen to be wrong it shouldn't be hard to adjust the code for them.

Categories

Resources