views:

81

answers:

6

Or How to if-statement in a modified list.

I've been reading StackOverflow for a while (thanks to everyone). I love it. I also seen that you can post a question and answer it yourself. Sorry if I duplicate, but I didn't found this particular answer on StackOverflow.


  • How do you verify if a element is in a list but modify it in the same time?

My problem:

myList = ["Foo", "Bar"]
if "foo" in myList:
  print "found!"

As I don't know the case of the element in the list I want to compare with lower case list. The obvious but ugly answer would be:

myList = ["Foo", "Bar"]
lowerList = []

for item in myList:
  lowerList.append(item.lower())

if "foo" in lowerList:
  print "found!"

Can I do it better ?

+1  A: 

List comprehensions:

mylist = ["Foo", "Bar"]
lowerList = [item.lower() for item in mylist]

Then you can do something like if "foo" in lowerlist or bypass the temporary variable entirely with if "foo" in [item.lower() for item in mylist]

Jason Scheirer
A: 

How about:

theList = ["Foo", "Bar"]
lowerCaseSet = set(x.lower for x in theList)

if "foo" in lowerCaseSet:
   print "found"

BTW. you shouldn't call your variable list as this word is already used by list type.

Piotr Czapla
Good point for the naming
Philippe
+4  A: 
if any(s.lower() == "foo" for s in list): print "found"
Wai Yip Tung
note: any() is slightly better than list comprehension because it stops as soon as the first item is found. Also it won't create a disposable temporary list.
Wai Yip Tung
+1 for answering Q as OP asked, using a generator expression
Tim McNamara
Am I right if I say that your answer and mine are the same ?
Philippe
@Philippe I've just checked that both answers (this and yours) behaves similary. `in` also stops when the first element is found.
Piotr Czapla
Edit: Nvrmind, my comment was wrong.
delnan
@Philippe, interesting, I haven't thought of writing it this way. They seem equivalent to me.
Wai Yip Tung
A: 

I will respond to myself as it can help someone else:

We can use Generator directly in the If-statement to generate the modified list on the go.

list = ["Foo", "Bar"]
if "foo" in (item.lower() for item in list):
  print "found!"

The parentheses around the for-statement IS the generator. It will compute all the item on the fly and so, we will be able to compare our string to the modified one.

This is very useful and save memory (especially for big list) so you don't have to create a second list and you can keep your first list intact.

The downside is that is make the code harder to understand when you read it (especially when you are not use to generator).

Philippe
4 different answers in 3 minutes. Wow good job !
Philippe
Another problem is the O(n*m) complexity of that approac. It the list is big enough it is much better to use sets especially if you are going to check for existence multiple times.
Piotr Czapla
+1  A: 

This combines the memory advantages of a generator expression with the speed gains from removing duplicates:

if "foo" in (s.lower() for s in set(list)): print "found"
Tim McNamara
A: 

Please do not use list as variable name, here is version which puts generator to variable and demonstrates, that generation stopped after finding the answer and did not exhaust the generator:

list_to_search = ["Foo", "Bar"]
lowergen = (item.lower() for item in list_to_search)
if "foo" in lowergen:
  print "found!"
print next(lowergen), 'is next after it'
Tony Veijalainen