Reputation: 18252
I'm trying to remove some items of a dict based on their key, here is my code:
d1 = {'a': 1, 'b': 2}
d2 = {'a': 1}
l = [d1, d2, d1, d2, d1, d2]
for i in range(len(l)):
if l[i].has_key('b'):
del l[i]['b']
print l
The output will be:
[{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}]
Is there a better way to do it?
Upvotes: 0
Views: 309
Reputation: 172377
I like your way of doing it (except that you use a loop variable, but others pointed that out already), it's excplicit and easy to understand. If you want something that minimizes typing then this works:
[x.pop('b', None) for x in l]
Note though that only one 'b' will be deleted, because your list l references the dictionaries. So run your code above, and then print out d1, and you'll notice that in fact you deleted the b-key from d1 as well.
To avoid this you need to copy the dictionaries:
d1 = {'a': 1, 'b': 2}
d2 = {'a': 1}
l = [d1.copy(), d2.copy(), d1.copy(), d2.copy(), d1.copy(), d2.copy()]
[b.pop('b', None) for b in l]
d1 will now retain the b key.
Upvotes: 2
Reputation: 82
d1 = {'a': 1, 'b': 2} d2 = {'a': 1}
l = [d1, d2, d1, d2, d1, d2]
for i in range(len(l)): if l[i].has_key('b'): del l[i]['b']
print l
Here is little review of your code:
So your code becomes:
for item in l:
if 'b' in item:
del item['b']
One more thing you need to be careful is that on the first iteration that calls del, you will in fact delete all you need as d1 is mutable. You need to think that d1 is a reference and not the value (a bit like a pointer in C).
As Lennart Regebro mentioned to optimize your code you can also use list comprehension.
Upvotes: 0
Reputation: 26281
A slight simplification:
for d in l:
if d.has_key('b'):
del d['b']
Some people might also do
for d in l:
try:
del d['b']
except KeyError:
pass
Catching exceptions like this is not considered as expensive in Python as in other languages.
Upvotes: 3
Reputation: 9936
d1 = {'a': 1, 'b': 2}
d2 = {'a': 1}
l = [d1, d2, d1, d2, d1, d2]
for d in l:
d.pop('b',None)
print l
Upvotes: 16