I'm new to Python and stuck at something basic.
Say there's a list of dictionaries as follows:
[{key1:value1},{key2:value2},...{keyn:valuen}]
is there a pythonic way of extracting the dictionary
{key1:value1},{key2:value2},...{keyn:valuen}
I'm assuming you mean that you want {key1: value1, key2:value2, keyn:valuen}. That is, you want to combine all the separate dictionaries into a single one with each of the keys and values from the individual dictionaries.
Here's how I'd do it, using a dictionary comprehension:
l = [{"key1":"value1"},{"key2":"value2"},{"keyn":"valuen"}]
result = {k:v for d in l for k, v in d.iteritems()}
print result # {'key2': 'value2', 'key1': 'value1', 'keyn': 'valuen'}
Same thing, in perhaps an easier way to read:
result = {}
d_list = [{"key1": "value1"}, {"key2": "value2"}, {"keyn": "valuen"}]
for d in d_list:
for k, v in d.iteritems():
result[k] = v
a=[{1:1},{2:2},{3:3}]
result=dict([(k,v) for x in a for k,v in x.items()])
print result //{1: 1, 2: 2, 3: 3}
Related
I have a dictionary of key-value pairs, where the value is itself a dictionary. I would like to change the names of key values in that nested dictionary based on a predefined conversion.
I am using two lists to match up the values of the nested keys that I am trying to conver (Old_item1 should become New_item1):
comparison_list = ['Old_item1', 'Old_item2']
new_prods = ['New_item1', 'New_item2']
old_dict = {
'Company1':
{
'Old_item1':
{
'key1': val,
'key2': val
},
'Old_item2':
{
'key1': val,
'key2': val
}
}
}
I tried this:
new_dict = {}
for i in comparison_list:
for j in new_prods:
new_dict['Company1'][j] = test['Company1'][i]
I get a KeyError: KeyError: 'Company1'
The desired output for each item I add to each list is:
new_dict = {
'Company1':
{
'New_item1':
{
'key1': val # old item key, val
'key2': val # old item key, val
}
}
}
You can make a dictionary of mappings from the old to the new items, and then use it to create a new sub-dictionary for each company. This then needs to be wrapped inside an outer loop over companies (although here there is only one).
For example:
comparison_list = ['Old_item1', 'Old_item2']
new_prods = ['New_item1', 'New_item2']
old_dict = {'Company1':
{'Old_item1':
{'key1': 2,
'key2': 3},
'Old_item2':
{'key1': 4,
'key2': 5}}}
key_mappings = dict(zip(comparison_list, new_prods))
new_dict = {k: {key_mappings[k1]: v1 for k1, v1 in v.items()}
for k, v in old_dict.items()}
print(new_dict)
gives:
{'Company1': {'New_item1': {'key1': 2, 'key2': 3}, 'New_item2': {'key1': 4, 'key2': 5}}}
Here is the mappings dictionary key_mappings which we used:
{'Old_item1': 'New_item1', 'Old_item2': 'New_item2'}
The easiest way to go about this is to re-create your dictionary with a comprehension:
new_dict = {company: update_item(v) for company, v in old_dict.items()}
Then parse out update_item to it's own function. You could do this inline but it makes it difficult to understand.
conversion_lookup = {
'Old_item1': 'NewItem1',
'Old_item2': 'NewItem2',
}
def update_item(item: dict) -> dict:
return { conversion_lookup.get(k, k): v for k, v in item.items() }
new_dict = {company: update_item(v) for company, v in old_dict.items()}
For the conversion here I'm using a dictionary describing the conversion. If you need to construct this automatedly:
comparison_list = ['Old_item1', 'Old_item2']
new_prods = ['New_item1', 'New_item2']
conversion_lookup = { v: new_prods[idx] for idx, v in enumerate(comparison_list) }
The reason I like a dictionary is that you can use some_dict.get(a_value, a_default_value). Then, if your value isn't in your conversion dictionary you can fall back to the original value. That's what I'm doing here:
conversion_lookup.get(k, k)
The second k is the original item's value, which is a good thing to use if your conversion list doesn't include what you want.
One approach is to do it step by step. First create the dicts with the new names and old keys, then remove the old keys, and finally add in the new names.
# Keep the values from the old keys
values = [old_dict['Company1'][old_name] for old_name in comparison_list]
# Remove old names, and add in the
for new_key, value, old in zip(new_prods, values, comparison_list):
old_dict['Company1'].pop(old)
old_dict['Company1'][new_key] = value
I have a solution to this question, but I'm curious if there might be a better way.
I have a dict like this:
dict1 = {
'key1':[['value1','value2','value3'],['value4','value5','value6']],
'key2':[['value7','value8','value9'],['value10','value11','value12']],
'key3':[['value13','value14','value15'],['value16','value17','value18']]}
I want to convert this into a nested list, and inserting the keys into the new sublist like this:
nestedlist = [
['value1','value2','key1','value3'],['value4','value5','key1','value6'],
['value7','value8','key1','value9'],['value10','value11','key2','value12'],
['value13','value14','key2','value15'],['value16','value17','key2','value18'],
['value10','value11','key3','value12'],['value13','value14','key3','value15'],
['value16','value17','key3','value18']]
I solve this the following way:
keys = [*dict1]
newlist = []
for item in keys:
for item2 in dict1[item]:
item2.insert(2,item)
newlist.append(item2)
so, how can i improve this piece of code?
Here is one way via a list comprehension:
res = [[w[0], w[1], k, w[2]] for k, v in dict1.items() for w in v]
# [['value1', 'value2', 'key1', 'value3'],
# ['value4', 'value5', 'key1', 'value6'],
# ['value7', 'value8', 'key2', 'value9'],
# ['value10', 'value11', 'key2', 'value12'],
# ['value13', 'value14', 'key3', 'value15'],
# ['value16', 'value17', 'key3', 'value18']]
I would've done it pretty similarly. The only differences shown here:
result = []
for k, l in dict1.items():
for ll in l:
ll.insert(2, k)
result.append(ll)
No need to do list unpacking or doing [] accessing on dict1. items() returns a list of tuples containing each key and value of the dict.
What is the best way to create a dict from two other dicts (very big one and small one)?
We have:
big_dict = {
'key1':325,
'key2':326,
'key3':327,
...
}
small_dict = {
325:0.698,
326:0.684,
327:0.668
}
Needs to get a dict for data in small_dict, but we should use keys from big_dict:
comb_dict = {
'key1':0.698,
'key2':0.684,
'key3':0.668
}
The following code works with all cases (example shown in the driver values), with a more EAFP oriented approach.
>>> d = {}
>>> for key,val in big_dict.items():
try:
d[key] = small_dict[val]
except KeyError:
continue
=> {'key1': 0.698, 'key2': 0.684, 'key3': 0.668}
#driver values :
IN : big_dict = {
'key1':325,
'key2':326,
'key3':327,
'key4':330 #note that small_dict[330] will give KeyError
}
IN : small_dict = {
325:0.698,
326:0.684,
327:0.668
}
Or, using Dictionary Comprehension :
>>> {key:small_dict[val] for key,val in big_dict.items() if val in small_dict}
=> {'key1': 0.698, 'key2': 0.684, 'key3': 0.668}
If there are values in big_dict that may not be present as keys in small_dict, this will work:
combined_dict = {}
for big_key, small_key in big_dict.items():
combined_dict[big_key] = small_dict.get(small_key)
Or you might want to use a different default value instead with:
combined_dict[big_key] = small_dict.get(small_key, default='XXX')
Or you might want to raise a KeyError to indicate a problem with your data:
combined_dict[big_key] = small_dict[small_key]
Or you might want to skip missing keys:
if small_key in small_dict:
combined_dict[big_key] = small_dict[small_key]
You could use dictionary comprehension:
comb_dict = {k: small_dict[v] for k, v in big_dict.iteritems()}
If big_dict may contain values that are not keys in small_dict you could just ignore them:
comb_dict = {k: small_dict[v] for k, v in big_dict.iteritems() if v in small_dict}
or use the original value:
{k: (small_dict[v] if v in small_dict else v) for k, v in big_dict.iteritems()}
(Use items() in Python3)
keys = small_dict.keys()
combined_dict = {k:small_dict[v] for k,v in big_dict.items() if v in keys}
>>> combined_dict
{'key3': 0.668, 'key2': 0.684, 'key1': 0.698}
I need to do a not "natural" operation on a dictionary so i wondering what is the best pythonic way to do this.
I need to simplify a dictionary by removing all the keys on it with the same value (keys are differents, values are the same)
For example:
Input:
dict = {key1 : [1,2,3], key2: [1,2,6], key3: [1,2,3]}
expected output:
{key1 : [1,2,3], key2:[1,2,6]}
I dont care about which key is delete (on the example: key1 or key3)
Exchange keys and values; duplicated key-value pairs will be removed as a side effect (because dictionary does not allow duplicated keys). Exchange keys and values again.
>>> d = {'key1': [1,2,3], 'key2': [1,2,6], 'key3': [1,2,3]}
>>> d2 = {tuple(v): k for k, v in d.items()} # exchange keys, values
>>> d = {v: list(k) for k, v in d2.items()} # exchange again
>>> d
{'key2': [1, 2, 6], 'key1': [1, 2, 3]}
NOTE: tuple(v) was used because list is not hashable; cannot be used as key directly.
BTW, don't use dict as a variable name. It will shadow builtin function/type dict.
This solution deletes the keys with same values without creating a new dictionary.
seen = set()
for key in mydict.keys():
value = tuple(mydict[key])
if value in seen:
del mydict[key]
else:
seen.add(value)
I think you can do it this way also. But I don't say as there seems to be more efficient ways. It is in-line.
for i in dictionary.keys():
if dictionary.values().count(dictionary[i]) > 1:
del dictionary[i]
You can iterate over your dict items and use a set to check what we have seen so far, deleting a key if we have already seen the value:
d = {"key1" : [1,2,3], "key2": [1,2,6], "key3": [1,2,3]}
seen = set()
for k, v in d.items(): # list(items) for python3
temp = tuple(v)
if temp in seen:
del d[k]
seen.add(temp)
print(d)
{'key1': [1, 2, 3], 'key2': [1, 2, 6]}
This will be more efficient that using creating a dict and reversing the values as you only have to cast to tuple once not from a tuple back to a list.
this worked for me:
seen = set()
for key in mydict.copy():
value = tuple(mydict[key])
if value in seen:
del mydict[key]
else:
seen.add(value)
In python... I have a list of elements 'my_list', and a dictionary 'my_dict' where some keys match in 'my_list'.
I would like to search the dictionary and retrieve key/value pairs for the keys matching the 'my_list' elements.
I tried this...
if any(x in my_dict for x in my_list):
print set(my_list)&set(my_dict)
But it doesn't do the job.
(I renamed list to my_list and dict to my_dict to avoid the conflict with the type names.)
For better performance, you should iterate over the list and check for membership in the dictionary:
for k in my_list:
if k in my_dict:
print(k, my_dict[k])
If you want to create a new dictionary from these key-value pairs, use
new_dict = {k: my_dict[k] for k in my_list if k in my_dict}
Don't use dict and list as variable names. They shadow the built-in functions. Assuming list l and dictionary d:
kv = [(k, d[k]) for k in l if k in d]
new_dict = dict((k, v) for k, v in dict.iteritems() if k in list)
Turning list into a set set(list) may yield a noticeable speed increase
Try This:
mydict = {'one': 1, 'two': 2, 'three': 3}
mykeys = ['three', 'one','ten']
newList={k:mydict[k] for k in mykeys if k in mydict}
print newList
{'three': 3, 'one': 1}
What about print([kv for kv in dict.items() if kv[0] in list])
Here is a one line solution for that
{i:my_dict[i] for i in set(my_dict.keys()).intersection(set(my_list))}