given a dictionary with N keys and a tuple of K keys, K<=N is there a pythonic way to get a dictionary with only the K keys?
ex.
orig_dict = {'key1':'value1', 'key2':'value2', ..., 'keyN':'valueN'}
tuple = ('key2', 'keyM')
newdict = myFunc(orig_dict, tuple)
print newdict
Output:
'key2':'value2', 'keyM':'valueM'
You can use a dictionary comprehension:
{k:v for k,v in orig_dict.iteritems() if k in tuple_keys}
Observe:
>>> orig_dict = {'key1':'value1', 'key2':'value2', 'keyN':'valueN'}
>>> tuple_keys = ('key2', 'keyN')
>>> {k:v for k,v in orig_dict.iteritems() if k in tuple_keys}
{'keyN': 'valueN', 'key2': 'value2'}
Just use a comprehension:
tple = ('key2', 'keyM')
{k: orig_dict[k] for k in tple}
Or if you prefer functional:
from operator import itemgetter
dict(zip(tple, itemgetter(*tple)(orig_dict)))
What is more pythonic is debatable, what is definitely not pythonic is using tuple as a variable name.
If some keys may not exist you can get the intersection with viewkeys:
dict(zip(tuple, itemgetter(*orig_dict.viewkeys() & tple)(orig_dict)))
{k : orig_dict[k] for k in orig_dict.viewkeys() & tple}
For python3 just use .keys() which returns a dict_view object as opposed to a list in python2.
If you wanted to give a default value of None for missing keys, you could also use map with dict.get so missing keys would have their value set to None.
dict(zip(tuple, map(orig_dict.get, tuple)
Use a dictionary comprehension
orig_dict = {'key1':'value1', 'key2':'value2', 'keyN':'valueN'}
keys = ('key2', 'keyM')
>>> {k:orig_dict[k] for k in keys if k in orig_dict}
{'key2': 'value2'}
This will be more efficient than iterating over the dictionary's keys and checking whether the key exists in the tuple because it is an O(1) operation to lookup a dict vs O(n) to search in a tuple.
Alternatively you can use a set to get the common keys and combine that with a dict comprehension:
>>> {k:orig_dict[k] for k in set(keys).intersection(orig_dict)}
{'key2': 'value2'}
Related
Two dictionaries:
dict1 = {'firstvalue':1, 'secondvalue':2, 'fourthvalue':4}
dict2 = {'firstvalue':1, 'thirdvalue':3, 'fourthvalue':5}
I get set(['secondvalue']) as a result upon doing:
dict1.viewkeys() - dict2
I need {'secondvalue':2} as a result.
When I use set, and then do the - operation, it does not give the desired result as it consists of {'fourthvalue:4} as well.
How could I do it?
The problem with - is that (in this context) it is an operation of dict_keys and thus the results will have no values. Using - with viewitems() does not work, either, as those are tuples, i.e. will compare both keys and values.
Instead, you can use a conditional dictionary comprehension, keeping only those keys that do not appear in the second dictionary. Other than Counter, this also works in the more general case, where the values are not integers, and with integer values, it just checks whether a key is present irrespective of the value that is accociated with it.
>>> dict1 = {'firstvalue':1, 'secondvalue':2, 'fourthvalue':4}
>>> dict2 = {'firstvalue':1, 'thirdvalue':3, 'fourthvalue':5}
>>> {k: v for k, v in dict1.items() if k not in dict2}
{'secondvalue': 2}
IIUC and providing a solution to Finding a key-value pair present only in the first dictionary as specified, you could take a set from the key/value pairs as tuples, subtract both sets and construct a dictionary from the result:
dict(set(dict1.items()) - set(dict2.items()))
# {'fourthvalue': 4, 'secondvalue': 2}
Another simple variation with set difference:
res = {k: dict1[k] for k in dict1.keys() - dict2.keys()}
Python 2.x:
dict1 = {'firstvalue':1, 'secondvalue':2, 'fourthvalue':4}
dict2 = {'firstvalue':1, 'thirdvalue':3, 'fourthvalue':5}
keys = dict1.viewkeys() - dict2.viewkeys()
print ({key:dict1[key] for key in keys})
output:
{'secondvalue': 2}
I have two dictionaries like this:
my_nested_dictionary= {'key5': 'value5',
'key6': {'inner_key6_1': 'inner_value6_1'},
'key7': 'value7'}
empty_dict = {}
If I want to update empty_dict with an inner dict from my_nested_dictionary, I can do that with this code:
for key, value in my_nested_dictionary.iteritems():
if key=='key6':
empty_dictionary.update(value)
However, is there any universal way to do this without using an 'if condition' hardcoded for exactly one key? If I had more nested dictionaries as a value of more keys in my_nested_dictionary, is there a way to update empty_dictionary with all of them at once?
If you don't need to update an existing dictionary and just want a dictionary containing only nested dictionaries, you can do this instead:
only_nested = {k: v for k, v in my_nested_dictionary.items() if isinstance(v, dict)}
For example, given this code:
my_nested_dictionary = {'key5': 'value5',
'key6': {'inner_key6_1': 'inner_value6_1'},
'key7': 'value7',
'key8': {'inner_key8_1': 'inner_value8_1'}}
only_nested = {k: v for k, v in my_nested_dictionary.items() if isinstance(v, dict)}
print(only_nested)
We get this output:
{'key6': {'inner_key6_1': 'inner_value6_1'}, 'key8': {'inner_key8_1': 'inner_value8_1'}}
If you want to check a nested dictionary;
for key, value in my_nested_dictionary.iteritems():
if isinstance(value, dict):
empty_dictionary.update(value)
If you would like to get just get the keys in one statement without using a if, you can do it like (Python 3):
output = list(filter(lambda key: isinstance(my_nested_dictionary[key], dict), my_nested_dictionary.keys()))
output will be like ['key 7'].
From there, you can look it up the vales from the original dictionary as you like. This way you don't have to multiple copies of the same objects.
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.
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))}