user2259908
user2259908

Reputation: 47

How do I return the index of a group of values from a list for a specific value in the group?

If I have the list:

list1 = [(12, "AB", "CD"), (13, "EF", "GH"), (14, "IJ", "KL")]

I want to get the index of the group that has the value 13 in it:

if 13 in list1[0]:
      idx = list1.index(13)
      item = list1[idx]
      print str(item)

      [13, EF, GH]

When I try this, I keep getting "Index not in list", even though it is passing the if statement because it is finding the value 13 within the list.

Upvotes: 2

Views: 123

Answers (2)

msw
msw

Reputation: 43527

Given the added criterion from the comment "I really don't care where they are in the list" the task becomes much easier and far more obvious

def get_ids(id, tuple_list):
    """returns members from tuple_list whose first element is id"""
    return [x for x in tuple_list if x[0] == id]

This isn't as expensive as one might expect if you recall that tuples are immutable objects. When the interpreter builds the new list, it only contains the internal id (reference) of the tuples of interest. This is in keeping with the original question asking for a list of indices. List comprehensions as used here are an efficient way of constructing new lists as much of the work is done internal to the interpreter. In short, many intuitions from C-like languages about performance don't apply well to Python.

As Ashwini noted, if the id numbers in the tuples are unique, and you are making multiple queries, then a dictionary might be a more suitable structure. Even if the id numbers aren't unique, you could use a dictionary of lists of tuples, but it is best to do the clearest thing first and not guess at the performance in advance.

As with the dictionary example, because an empty list is "falsey" in Python, you can use the same sort of conditional:

hits = get_ids(13, list1)
if hits:
    # we got at least one tuple back
else:
    # no 13s to be had

Upvotes: 0

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 251116

You can use next and enumerate:

>>> list1 = [(12, "AB", "CD"), (13, "EF", "GH"), (14, "IJ", "KL")]
>>> next(i for i,x in enumerate(list1) if 13 in x)
1

With a simple for-loop:

for i, item in enumerate(list1):
     if 13 in item:
         print i
         break
...         
1

Update:

If the first item in each tuple is unique and you're doing this multiple times then create a dict first. Dicts provide O(1) lookup while lists O(N)

>>> list1 = [(12, "AB", "CD"), (13, "EF", "GH"), (14, "IJ", "KL")]
>>> dic = {x[0]:x[1:]  for x in list1}

Accessing items:

>>> dic[12]
('AB', 'CD')
>>> dic[14]
('IJ', 'KL')
#checking key existence
>>> if 17 in dic:          #if a key exists in dic then do something
       #then do something

Upvotes: 3

Related Questions