Removing key values pairs from a list of dictionaries - python

I have a list of dictionaries such as:
[{'mykey1':'myvalue1', 'mykey2':'myvalue2'}, {'mykey1':'myvalue1a', 'mykey2':'myvalue2a'}]
I need to remove all key values pairs from all dictionaries where the key is equal to mykey1. I could do this by looping through and using the del statement, but I am wondering how I would create a new list using list comprehensions or lambdas which would just remove all key value pairs where the key was mykey1.
Many thanks

If you really want to use a list comprehension, combine it with a dict comprehension:
[{k: v for k, v in d.iteritems() if k != 'mykey1'} for d in mylist]
Substitute .iteritems() for .items() if you are on python 3.
On python 2.6 and below you should use:
[dict((k, v) for k, v in d.iteritems() if k != 'mykey1') for d in mylist]
as the {key: value ...} dict comprehension syntax was only introduced in Python 2.7 and 3.

def new_dict(old_dict):
n = old_dict.copy()
n.pop('mykey1',None)
return n
new_list_of_dict = map(new_dict,list_of_dict)
or
new_list_of_dict = [ new_dict(d) for d in list_of_dict ]
Rather than using del, I opted for dict.pop since pop will suppress the KeyError if the key doesn't exist.
If you really only want to get certain keys, this becomes a bit easier.
from operator import itemgetter
tuple_keys = ('key1','key2','key3')
get_keys = itemgetter(*tuple_keys)
new_dict_list = [ dict(zip(tuple_keys,get_keys(d)) for d in old_dict_list ]
which raises KeyError if the keys aren't in the old dict
Or:
new_dict_list = [ dict( (k,d.get(k,None)) for k in tuple_keys ) for d in old_dict_list ]
which will also add key:None if key isn't in the old dict. If you don't want that None, you could do:
new_dict_list = [ dict( (k,d[k]) for k in tuple_keys if k in d) for d in old_dict_list ]
Depending on what percent of the dictionary you're including/excluding and the size of the dictionaries, this might be slightly faster than the solution by #MartijnPieters.

You can follow this simple step :
arr = [{'mykey1':'myvalue1', 'mykey2':'myvalue2'}, {'mykey1':'myvalue1a', 'mykey2':'myvalue2a'}]
for i in arr:
del i["mykey1"]
print(arr)
output:
[{'mykey2': 'myvalue2'}, {'mykey2': 'myvalue2a'}]

On python 3.5 this works successfully
'''result is my list dict'''
[{key: value for key, value in dict.items() if key != 'EQUITY'} for dict in result]

[d.pop('mykey1', None) for d in list]

Related

Transform dictionary key-value pairs to list of tuples

I have a dictionary of lists:
dic = {'contig_100003': ['contig_14576'], 'contig_100022': ['contig_96468'], 'contig_100023': ['contig_24939', 'contig_33444', 'contig_72441']}
And I would like to get a list (including the key) of it:
List = [(contig_100003','contig_14576'), (contig_100022','contig_96468'), (contig_100023','contig_24939', 'contig_33444', 'contig_72441')]
However, my code cannot get rid of the internal/value list:
list(dic.items())
[('contig_100003', ['contig_14576']),
('contig_100022', ['contig_96468']),
('contig_100023', ['contig_24939', 'contig_33444', 'contig_72441'])]
This might solve it
[(k, *v) for k, v in dic.items()]
You can use tuple concatenation to get the desired output:
result = [(key,) + tuple(value) for key, value in dic.items()]
print(result)
This outputs:
[('contig_100003', 'contig_14576'), ('contig_100022', 'contig_96468'),
('contig_100023', 'contig_24939', 'contig_33444', 'contig_72441')]

Adding additional logic to a lambda function to get the minimum value from a python dictionary

I have a dictionary with values mapping some object to an integer; e.g. {node: 1, node: 2}.
I want to get the key that corresponds to the minimum value in this dictionary, which I know I can do with:
min_key = min(my_dict, key=lambda k: my_dict[k])
However, I'd also like to add the constraint that the key is not contained within some other set. Here's the pseudo-code that I wished worked:
min_key = min(my_dict, key=lambda k: my_dict[k] where k not in my_set)
Is there a way to write this as a one-liner in python as part of a lambda, or do I now have to explicitly loop through the dictionary and add the logic within the loop like this?
min_key, min_value = None, float('inf')
for k,v in my_dict.items():
if v < min_value and k not in my_set:
min_key = k
return min_key
Replace my_dict with a dictionary comprehension that returns the filtered dictionary.
min_key = min({k:v for k, v in my_dict.items() if k not in my_set},
key = lambda k: my_dict[k])
Just take the minimum over the filtered keys instead of all keys:
min_key = min(my_dict.keys() - my_set, key=my_dict.get)
(Note I also replaced your key function, no need to write your own.)
It's similar to #Barmar's answer but you can also use set.difference between my_dict and my_set to filter the relevant dictionary:
out = min(set(my_dict).difference(my_set), key = lambda k: my_dict[k])

How to split list inside a dictionnary to create a new one?

I've been struggling on something for the day,
I have a dictionnary under the format
dict = {a:[element1, element2, element3], b:[element4, element5, element6]...}
I want a new dictionnary under the form
newdict = {a:element1, b:element4...}
Meaning only keeping the first element of the lists contained for each value.
You can use a dictionary comprehension:
{k: v[0] for k, v in d.items()}
# {'a': 'element1', 'b': 'element4'}
Hopefully this helps.
I like to check if the dictionary has a key before overwriting a keys value.
dict = {a:[element1, element2, element3], b:[element4, element5, element6]}
Python 2
newDict = {}
for k, v in dict.iteritems():
if k not in newDict:
# add the first list value to the newDict's key
newDick[k] = v[0]
Python 3
newDict = {}
for k, v in dict.items():
if k not in newDict:
# add the first list value to the newDict's key
newDick[k] = v[0]

Extract all single {key:value} pairs from dictionary

I have a dictionary which maps some keys to 1 or more values.
In order to map to more than 1 value, I'm mapping each individual key to a list. How can I get the number of the single pairs? Is there a quick pythonic way to do this?
My dict looks something like this:
>>print dict
{'key1':['value11',value12, ...], 'key2': ['value21'], 'key3':['value31', 'value32']}
So in the above example, I would expect my output to be 1
With d being the dictionary:
sum(len(v) == 1 for v in d.values())
Or:
map(len, d.values()).count(1)
(The latter requires list around the map if you're using Python 3.)
You could try something like
len([_ for v in d.values() if len(v) == 1])
where d is the name of your dictionary (you should avoid using identifiers such as dict, incidentally).
Depending on your interpreter version, you might need to use itervalues instead of values.
You can use #MosesKoledoye's solution for the short (and probably a tiny bit faster) solution, or this naive version:
print(len([value for value in d.values()
if hasattr(value, '__len__') and len(value) == 1]))
Iterate through values in dictionary and count:
count = 0
for value in dic.values():
if len(value) == 1:
count += 1
print count
You could just filter your dictionary out like this:
data = {
'key1': ['value11', 'value12'],
'key2': ['value21'],
'key3': ['value31', 'value32']
}
result = filter(lambda (k, v): len(v) == 1, data.iteritems())
print result, "=>", len(result)

Python dictionary: Remove all the keys that begins with s

I've got a dictionary like
dic = {'s_good': 23, 's_bad': 39, 'good_s': 34}
I want to remove all the keys that begins with 's_'
So in this case first two will be removed.
Is there any efficient way to do so?
This should do it:
for k in dic.keys():
if k.startswith('s_'):
dic.pop(k)
for k in dic.keys():
if k.startswith('s_'):
del dic[k]
* EDIT *
now in python 3 , years after the original answer, keys() returns a view into the dict so you can't change the dict size.
One of the most elegant solutions is a copy of the keys:
for k in list(dic.keys()):
if k.startswith('s_'):
del dic[k]
With python 3 to avoid the error:
RuntimeError: dictionary changed size during iteration
This should do it:
list_keys = list(dic.keys())
for k in list_keys:
if k.startswith('s_'):
dic.pop(k)
You can use a dictionary comprehension:
dic = {k: v for k, v in dic.items() if not k.startswith("s_")}
Note that this creates a new dictionary (which you then assign back to the dic variable) rather than mutating the existing dictionary.
How about something like this:
dic = dict( [(x,y) for x,y in dic.items() if not x.startswith('s_')] )

Categories