0

I have a list like this:

l = [{'username': u'bob', 'id': 2L, 'email': u'bob@me.com'}, {'username': u'jane', 'id': 3L, 'email': u'jane@me.com'}]

So I'm wondering what is the best way to remove the bob object from the list?

I know how to use remove() to eliminate an element, but not sure to eliminate a whole object.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
Jand
  • 2,527
  • 12
  • 36
  • 66
  • Probably a dupe of http://stackoverflow.com/questions/4915920/how-to-delete-an-item-in-a-list-if-it-exists-python/4915964#4915964 – Paulo Scardine Oct 09 '15 at 18:21
  • What is the difference between eliminating an element and a whole object? – Scott Hunter Oct 09 '15 at 18:21
  • Python garbage collector is by reference count. It will delete the object when there is no variables referencing it left in scope. – Paulo Scardine Oct 09 '15 at 18:22
  • @PauloScardine: Is that supposed to be an answer to my question? Isn't *every* element of a list an object? – Scott Hunter Oct 09 '15 at 18:24
  • 1
    IIUC, you know how to remove the item from the list but are concerned about destroying it. Every value in Python is an object, and every item in a list is a reference to a value. Think about it as pointers. When you remove an object from the array and there is no variable, array or object property referencing it, the object will be wiped from memory. Most of the time you don't have to worry about it. – Paulo Scardine Oct 09 '15 at 18:29

3 Answers3

1

Use list comprehension and filter out the unwanted object, like this

>>> [item for item in l if item['username'] != 'bob']
[{'email': 'jane@me.com', 'username': 'jane', 'id': 3}]

Alternatively you can use filter function also, like this

>>> filter(lambda item: item['username'] != 'bob', l)
[{'email': 'jane@me.com', 'username': 'jane', 'id': 3}]

Note: Both these methods return a new list without the item you don't want. They don't change the original object.

thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • 1
    @Jand List comprehension is known to be faster than `filter` in most of the cases. – thefourtheye Oct 09 '15 at 18:39
  • That depends on the size of the list and the Python version. Also, "better performance" depends if you are concerned about speed or memory consumption, often there is a trade-off. – Paulo Scardine Oct 09 '15 at 18:39
  • @PauloScardine my version is 2.7. How does it make difference? – Jand Oct 09 '15 at 18:41
  • 1
    Yes, it does. in Python 2.x, `filter(function, iterable)` used to be equivalent to `[item for item in iterable if function(item)]` (or `[item for item in iterable if item]` if the first argument is `None`); in Python 3.x, it is now equivalent to `(item for item in iterable if function(item))`. The subtle difference is that filter used to return a list, now it works like a generator expression - this is OK if you are only iterating over the cleaned list and discarding it, but if you really need a list, you have to enclose the `filter()` call within a `list()` constructor. – Paulo Scardine Oct 09 '15 at 18:45
1

You can use a list comprehension to loop over the list and keep the dictionaries that those username value is not bob:

>>> [_dic for _dic in l if _dic.get('username','')!='bob']
[{'username': u'jane', 'id': 3L, 'email': u'jane@me.com'}]

Note that using dict.get you can set a default value for this method which returns it if your dictionaries have not the key username, so it won't raise an KeyError.

Mazdak
  • 105,000
  • 18
  • 159
  • 188
0

The following will return all the objects which username is not bob:

l2 = filter(lambda x: x['username'] != 'bob', l)

Now if you print l2, you'll get:

[{'email': u'jane@me.com', 'id': 3L, 'username': u'jane'}]
kakhkAtion
  • 2,264
  • 22
  • 23