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 argumentnone); 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 enclosefilter()calllist()constructor. - *these lispy flavored constructs considered little alien in python. around 2005, guido talking dropping
filter- along companionsmap,reduce(they not gone yetreducemoved 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) - see this python history blog post gvr.
- this syntax inspired set-builder notation in math.
- python 3 has set , dict comprehensions.
notes
- you may want use inequality operator
!=instead ofis not(the difference important) - for critics of methods implying list copy: contrary popular belief, generator expressions not more efficient list comprehensions - please profile before complaining
Comments
Post a Comment