views:

109

answers:

5

I have a list of dicts:

list =  [{'title': u'Politics', 'id': 1L, 'title_url': u'Politics'}, 
         {'id': 3L, 'title_url': u'Test', 'title': u'Test'}]

I'd like to remove the list item with title = 'Test'

What is the best way to do this given that the order of the key/value pairs change?

Thanks.

+4  A: 
mylist = [x for x in mylist if x['title'] != 'Test']

Other solutions are possible, but any solution will be O(n) since you have to search through the whole list for the right element. Given that, go with the simplest approach.

Daniel Stutzbach
what is `where`?
SilentGhost
@SilentGhost: thanks, fixed. :-)
Daniel Stutzbach
+6  A: 
[i for i in lst if i['title']!= u'Test']

Also, please don't use list as a variable name, it shadows built-in.

SilentGhost
You want !=, not ==. He wants to remove just that item.
Daniel Stutzbach
@Daniel: thanks, fixed
SilentGhost
+3  A: 
L = [{'title': u'Politics', 'id': 1L, 'title_url': u'Politics'}, 
     {'id': 3L, 'title_url': u'Test', 'title': u'Test'}]
L = [d for d in L if d['title'] != u'Test']

Tips: The items in a dict aren't ordered anyway. Using the name of a built-in function like list as a variable name is a bad idea.

Ben James
+3  A: 

More verbose than the above answers but modify the list in place rather than creating a copy of it (Have no idea which would be faster - copying might be the way to go anyway!)

lst =  [{'title': u'Politics', 'id': 1L, 'title_url': u'Politics'},  
    {'id': 3L, 'title_url': u'Test', 'title': u'Test'}]  
for i in xrange(len(lst)-1,0,-1):  
if lst[i].get("title")=="Test":  
    del lst[i]  

Modifies the list in place rather than copying it, copes with removing multiple dicts which have "title":"Test" in them and copes if there's no such dict.

Note that .get("title") return None if there's no matching key whereas ["title"] raises an exception.

If you could guarantee there would be just one matching item you could also use (and wanted to modify in place rather than copy)

for i,d in enumerate(lst):  
    if d.get("title")=="Test":  
        del lst[i]  
        break  

Probably simplest to stick with

[x for x in lst if x.get("title")!="Test"]
pycruft
A: 
new_lst = filter(lambda x: 'title' in x and x['title']!=u'Test', lst)
Evgeny