6

I have been trying to delete multiple dictionaries in a list but I can only delete one at a time.

Below is the main code I am working on. Records is the list of dictionaries. I want to delete dictionaries that have 0 in them.

Records = [{'Name':'Kelvin','Price': 0},{'Name': 'Michael','Price':10}]

I want to delete dictionaries with Prices of 0

def deleteUnsold(self):
    for d in records:
        for key, value in d.items():
            if d['Price'] == 0:
                records.remove(d)
Lafexlos
  • 7,618
  • 5
  • 38
  • 53
MrKay
  • 63
  • 1
  • 6

3 Answers3

12

Use a list comprehension with an if condition

>>> Records = [{'Name':'Kelvin','Price': 0},{'Name': 'Michael','Price':10}]
>>> [i for i in Records if i['Price'] != 0]
[{'Price': 10, 'Name': 'Michael'}]

Check out if/else in Python's list comprehension? to learn more about using a conditional within a list comprehension.


Note that [as mentioned below] you can also leave out checking for the value 0. However this also works if Price is None, hence you may use the first alternative if you are not sure of the data type of the value of Price

>>> [i for i in Records if i['Price']]
[{'Price': 10, 'Name': 'Michael'}]
Community
  • 1
  • 1
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
  • 2
    You can probably omit the `is not 0` part (and I would've used `!= 0` instead, as I trust equality more than I trust integer interning). – TigerhawkT3 Jan 13 '16 at 09:49
  • @TigerhawkT3 In a moment – Bhargav Rao Jan 13 '16 at 09:50
  • I am not really conversant with list comprehension. How do I then add the delete statement? – MrKay Jan 13 '16 at 10:17
  • @MrKay - Read through the provided link on list comprehension. – TigerhawkT3 Jan 13 '16 at 10:19
  • Exactly @MrKay You do not need a delete statement when you are using a list comprehension. When you use a list comp you create a new list by selecting a few items from the original iterator. So you are not deleting anything from the original list. As mentioned in the [docs that I have linked in the answer](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions), it is a shortened form of writing a loop. – Bhargav Rao Jan 13 '16 at 10:20
  • @BhargavRao Perfectly answered. You must be a lecturer..haha – MrKay Jan 13 '16 at 10:24
  • @MrKay Read through the documentation clearly and very very slowly. If you don't understand list comps in general refer the [Wikipedia topic on list comprehensions.](https://en.wikipedia.org/wiki/List_comprehension) – Bhargav Rao Jan 13 '16 at 10:26
  • @MrKay Thanks for the kind words. – Bhargav Rao Jan 13 '16 at 10:26
  • @BhargavRao It works perfectly fine and I can print out the new list. One last thing, before I call this a wrap. How do I replace the old Records with the new one? – MrKay Jan 13 '16 at 10:33
  • That's simple `Records = [i for i in Records if i['Price'] != 0]` will do the job..... Also before leaving remember to [accept](http://meta.stackexchange.com/questions/5234) this answer if you think it solves your problem. It will community at large to recognize the correct solution. This can be done by clicking the green check mark next to the answer. See this [image](http://i.stack.imgur.com/uqJeW.png) for reference. Cheers. – Bhargav Rao Jan 13 '16 at 10:36
  • Hi @BhargavRao I know it's that simple, i tried it couple of times, but it gives me this error - local variable 'records' referenced before assignment – MrKay Jan 13 '16 at 10:39
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/100572/discussion-between-mrkay-and-bhargav-rao). – MrKay Jan 13 '16 at 10:43
  • Strictly speaking, this isn't deleting items, but making a new list. – tglaria Jan 13 '16 at 13:16
2

You can use filter:

print filter(lambda x:x['Price']!=0,Records)
Ahsanul Haque
  • 10,676
  • 4
  • 41
  • 57
  • 3
    It is considered 'less' pythonic, and list comprehension should be preferred. Also be careful that filter in python 3 returns an iterator and not a list. – Benoit Seguin Jan 13 '16 at 09:59
0

Okay, generally speaking you shouldn't remove items from a list you're iterating for, because that will probable make you miss some items of the list.

Now, about some other answer spoken here, yes, they work, but strictly speaking they're not removing/deleting items from the list: they're creating a new list and replacing the old variable with a new list.

What could be done:

for d in list(records):
    if d['Price'] == 0:
        records.remove(d)

for d in reversed(records):
    if d['Price'] == 0:
        records.remove(d)

for idx in range(len(records)-1,-1,-1):
    if records[idx]['Price'] == 0:
        records.pop(idx)

I like this one, though:

for d in records[::-1]:
    if d['Price'] == 0:
        records.remove(d)
tglaria
  • 5,678
  • 2
  • 13
  • 17
  • Please refer to these two deleted answers http://i.stack.imgur.com/anHx0.png for a complete discussion of your solution. Thanks – Bhargav Rao Jan 13 '16 at 14:12