-1

This is related to many similar questions like

Check if element exists in tuple of tuples

However I do not only want to check it it exist but in which of the tuples it is in, eg. the index. The data structures (from 3rd party library) is always a tuple of tuples. (it can't be nested any deeper).

What I want as return value is the index of the tuple the element is located in. I know I can for sure hack this together with for loops but is there any nicer way to get the index?

beginner_
  • 7,230
  • 18
  • 70
  • 127

3 Answers3

1

you may use next and enumerate built-in functions to have a nice way of getting the index. You may use it the following way:

def get_index_of_containing_tuple(lst: tuple, item):
    try:
        return next(ind for ind, tup in enumerate(lst) if item in tup)
    except Exception:
        return -1

Example of using it:

a = (('a', 'b'), ('c', 'd'))
get_index_of_containing_tuple(a, 'a')  # returns 0
get_index_of_containing_tuple(a, 'c')  # returns 1
get_index_of_containing_tuple(a, 'd')  # returns 1
get_index_of_containing_tuple(a, 123)  # returns -1
Razko
  • 551
  • 2
  • 7
0

Here's a solution without for loops. Indices of the inner tuples containing the queried element in the outer tuple a are returned as a list

list(filter(lambda x: x != -1, map(lambda enum: enum[0] if 'queried_element' in enum[1] else -1, enumerate(a)))
bui
  • 1,576
  • 1
  • 7
  • 10
0

For repeating tuple elements within in the nested tuple, you can easily manage with a single for loop.

example = (('apple','orange'),('orange','banana'),('banana','mango'))

def element_index(iterable, key = None):
    index = set()
    index_add = index.add
    
    for ix, element in enumerate(iterable):
        if key in element:
            index_add(ix)
            
    return index

nth_tuple(example, key = 'orange')

>> {0, 1}

The index method similarly looks into each element till reach first found. I think a for loop will work just fine as long it suits your needs and the nested tuple is not that large.

BernardL
  • 5,162
  • 7
  • 28
  • 47