python - How to delete an item in a list if it exists? -


i getting new_tag form text field self.response.get("new_tag") , selected_tags checkbox fields

self.response.get_all("selected_tags") 

i combine them this:

tag_string = new_tag new_tag_list = f1.striplist(tag_string.split(",") + selected_tags) 

(f1.striplist function strips white spaces inside strings in list.)

but in case tag_list empty (no new tags entered) there selected_tags, new_tag_list contains empty string " ".

for example, logging.info:

new_tag selected_tags[u'hello', u'cool', u'glam'] new_tag_list[u'', u'hello', u'cool', u'glam'] 

how rid of empty string?

if there empty string in list:

>>> s = [u'', u'hello', u'cool', u'glam'] >>> = s.index("") >>> del s[i] >>> s [u'hello', u'cool', u'glam'] 

but if there no empty string:

>>> s = [u'hello', u'cool', u'glam'] >>> if s.index(""):         = s.index("")         del s[i]     else:         print "new_tag_list has no empty string" 

but gives:

traceback (most recent call last):   file "<pyshell#30>", line 1, in <module>     if new_tag_list.index(""):         valueerror: list.index(x): x not in list 

why happen, , how work around it?

1) almost-english style:

test presence using in operator, apply remove method.

if thing in some_list: some_list.remove(thing) 

the removemethod remove first occurrence of thing, in order remove occurrences can use while instead of if.

while thing in some_list: some_list.remove(thing)     
  • simple enough, choice.for small lists (can't resist one-liners)

2) duck-typed, eafp style:

this shoot-first-ask-questions-last attitude common in python. instead of testing in advance if object suitable, carry out operation , catch relevant exceptions:

try:     some_list.remove(thing) except valueerror:     pass # or scream: thing not in some_list! except attributeerror:     call_security("some_list not quacking list!") 

off course second except clause in example above not of questionable humor totally unnecessary (the point illustrate duck-typing people not familiar concept).

if expect multiple occurrences of thing:

while true:     try:         some_list.remove(thing)     except valueerror:         break 
  • a little verbose specific use case, idiomatic in python.
  • this performs better #1
  • pep 463 proposed shorter syntax try/except simple usage handy here, not approved.

however, contextlib's suppress() contextmanager (introduced in python 3.4) above code can simplified this:

with suppress(valueerror, attributeerror):     some_list.remove(thing) 

again, if expect multiple occurrences of thing:

with suppress(valueerror):     while true:         some_list.remove(thing) 

3) functional style:

around 1993, python got lambda, reduce(), filter() , map(), courtesy of lisp hacker missed them , submitted working patches*. can use filter remove elements list:

is_not_thing = lambda x: x not thing cleaned_list = filter(is_not_thing, some_list) 

there shortcut may useful case: if want filter out empty items (in fact items bool(item) == false, none, zero, empty strings or other empty collections), can pass none first argument:

cleaned_list = filter(none, some_list) 
  • [update]: in python 2.x, filter(function, iterable) used equivalent [item item in iterable if function(item)] (or [item item in iterable if item] if first argument none); in python 3.x, equivalent (item item in iterable if function(item)). subtle difference filter used return list, works generator expression - ok if iterating on cleaned list , discarding it, if need list, have enclose filter() call list() constructor.
  • *these lispy flavored constructs considered little alien in python. around 2005, guido talking dropping filter - along companions map , reduce (they not gone yet reduce moved functools module, worth if high order functions).

4) mathematical style:

list comprehensions became preferred style list manipulation in python since introduced in version 2.0 pep 202. rationale behind list comprehensions provide more concise way create lists in situations map() , filter() and/or nested loops used.

cleaned_list = [ x x in some_list if x not thing ] 

generator expressions introduced in version 2.4 pep 289. generator expression better situations don't need (or want) have full list created in memory - when want iterate on elements 1 @ time. if iterating on list, can think of generator expression lazy evaluated list comprehension:

for item in (x x in some_list if x not thing):     do_your_thing_with(item) 

notes

  1. you may want use inequality operator != instead of is not (the difference important)
  2. for critics of methods implying list copy: contrary popular belief, generator expressions not more efficient list comprehensions - please profile before complaining

Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -