1

I have a list which looks like this:

List = [['name1','surname1'], ['name2','surname2'],['name3','surname3']]

I would like to check if "name1" is in the object "List". I have tried:

if 'name1' in List:
    print True
else:
    print False

and the output is 'False'. Any idea how to create a sublist (or something similar) to check the first element of every sub-list without looping through all the elements of the main list?

POSSIBLE SOLUTION

What I have thought about is:

for i in range(0, len(List)):
    if List[i][0] == 'name1':
        print True

but I want to avoid exactly this iteration with something more optimized, if possible.

Matteo NNZ
  • 11,930
  • 12
  • 52
  • 89
  • Optimized in terms of speed or code length? – tom Feb 14 '14 at 10:22
  • I'd say both, more important is speed, but also some code shortening would be highly appreciated. – Matteo NNZ Feb 14 '14 at 10:23
  • 1
    Then please explain why you are using a list of lists instead of e.g. a dict. – tom Feb 14 '14 at 10:24
  • 1
    Mmm, I'd say because I'm a newbie and still don't know very well all Python objects. I'll try to indagate the dictionaries solution, but as long as I keep on using lists maybe I better use list comprehension? – Matteo NNZ Feb 14 '14 at 10:28
  • 1
    Using a list of lists is fine if the list is small (say less than 30 elements) or if performance is not critical. – tom Feb 14 '14 at 10:37
  • Thanks a lot for this useful tip, I'll try to see how hard is to restore the code using dictionaries rather than lists. – Matteo NNZ Feb 14 '14 at 14:17

4 Answers4

7

You can use a generator expression:

>>> 'name1' in (x[0] for x in List)
True

This will short-circuit as soon as 'name1' is found and won't create any unnecessary list in memory.

Related: List comprehension vs generator expression's weird timeit results?

Community
  • 1
  • 1
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Great. I will choose this answer since it's the most optimized so far still using lists that I cannot easily change with dictionaries. Thanks a lot. – Matteo NNZ Feb 14 '14 at 10:33
2

I suggest using a dictionary, which seems more suitable here.

But if a list of lists is to be used, you can have such a code: 'name1' in [list[0] for list in List]

Max
  • 315
  • 1
  • 13
1

You can do it with:

if 'name1' in [l[0] for l in List]:

You can also add an if l at then end of the list comprehension just in case there's an empty list around:

if 'name1' in [l[0] for l in List if l]:  # safe if there's an empty list
Paulo Bu
  • 29,294
  • 6
  • 74
  • 73
  • Thanks for your answer, please check out my "Possible Solution" edit: isn't it this solution using the same iteration I have written? I was thinking about something a bit more optimized, if Python is offering any built-in of course :) – Matteo NNZ Feb 14 '14 at 10:22
  • Ain't the same. Normally list comprehension are faster and more elegant than a for loop. – Paulo Bu Feb 14 '14 at 10:23
  • I'm new to Python, but I'd like to understand this cause it's not really clear yet to me. How can a list comprehension be faster than a "traditional" for-loop, if the iterations is doing are exactly the same (check for every value in the list if something)? – Matteo NNZ Feb 14 '14 at 10:25
  • 1
    List comprehensions are done in C (in case of cpython). What this means is that the implicit `for` loop is taken care of in C, not python per se. A for loop in python create additional overhead. – Paulo Bu Feb 14 '14 at 10:27
1

More idiomatic way to do this, is to use any function

>>> any('name1' == current_list[0] for current_list in my_list)
True

This also short circuits on the first occurrence of name1.

Edit : In case, your name1 can be anywhere in the sub-list, you can use the in operator

>>> any('name1' in current_list for current_list in my_list)
True
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • Nice function that I didn't know, but I fear one problem. If I have: `List = [['John','Smith'], ['Andy', 'John']]`, is it gonna count two people named John while only one is actually named so? – Matteo NNZ Feb 14 '14 at 10:40
  • @MatteoNNZ It will not even check the second element since the first one has the name `John`. It short-circuits :) – thefourtheye Feb 14 '14 at 10:42
  • what about the case `List = [['Andrew','Smith'], ['Andy', 'John']]` for the name 'John'? Is the `'name1' == current_list[0]` saying to check "any" but only at the first position of every sub-list? Sorry if my questions are stupid but I'm programming in Python for not even a month :) – Matteo NNZ Feb 14 '14 at 10:47
  • 1
    @MatteoNNZ Thats okay. :) Please check my updated answer. `in` operator will check if the `name1` is there in the sub-list or not. – thefourtheye Feb 14 '14 at 10:49
  • Great. Thanks for the explanation, I'll assess which solution fits better with my needs ;) – Matteo NNZ Feb 14 '14 at 10:51