4

How do you know the index of an element that is in a sub list? A similar question was asked here for lists without nesting

Like so:

L=[[1, 2, 3], [4, 5, 6]]

What I want to be as output when the element is 3:

output=[0][2]
Community
  • 1
  • 1

6 Answers6

3

Try this:

def get_sublist_index(lists, item):
    for sublist in lists:
        if item in sublist:
            return lists.index(sublist), sublist.index(item)

>>> L=[[1,2,3],[4,5,6]]
>>> get_sublist_index(L, 3)
(0, 2)

Or to get every item:

def get_sublist_index(lists, item):
    for sublist in lists:
        if item in sublist:
            yield lists.index(sublist), sublist.index(item)

Making a generator:

>>> L=[[1,2,3],[4,3,6]]
>>> get_sublist_index(L, 3)
<generator object get_sublist_index at 0x1056c5e08>
>>> [i for i in get_sublist_index(L, 3)]
[(0, 2), (1, 1)]

Or if you don't want a generator:

def get_sublist_index(lists, item):
    outList = []
    for sublist in lists:
        if item in sublist:
            outList.append((lists.index(sublist), sublist.index(item)))
    return outList

>>> get_sublist_index(L, 3)
[(0, 2), (1, 1)]
>>> 
rassar
  • 5,412
  • 3
  • 25
  • 41
3
L=[[1,2,3],[4,5,6],[2,3,4,5,3]]

a = 3

print([(i,j) for i,x in enumerate(L) if a in x for j,b in enumerate(x) if b == a])
#[(0, 2), (2, 1), (2, 4)]

using list comprehension you can dig and return all the sub values. If you need to go deeper just keep chaining the list comprehension or write a function to do it.

MooingRawr
  • 4,901
  • 3
  • 24
  • 31
2

Perhaps something like this:

def find_sublist(outer, what):
    for i, lst in enumerate(outer):
        try:
            return i, lst.index(what)
        except ValueError:
            pass

Actually, output = [0][2] will throw an exception. Not sure what you mean by this. Do you want a tuple of two elements? I will assume you do.

You could alternatively use something more elegant, like

In [8]: [(i, sublist.index(3)) for i, sublist in enumerate(L) if 3 in sublist]
Out[8]: [(0, 2)]

In [9]: [(i, sublist.index(4)) for i, sublist in enumerate(L) if 4 in sublist]
Out[9]: [(1, 0)]
  • `find_sublist(L, 3)` only gives me an output of 0 and the OP says the output should be `0, 2` – rassar Dec 03 '16 at 15:10
2

"One-line" solution using numpy.where and numpy.transpose methods(the initial input array was extended to cover a complex case):

import numpy as np

L = [[1,2,3],[4,3,6]]  # 3 occurs twice
output = np.transpose(np.where(np.array(L) == 3))

print(output)

The output:

 [[0 2]
  [1 1]]
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
1

You should always count on enumerate for tasks that require indices and sequences:

def find_index(l, val=3):
    # res holds results
    res = []
    # Go through every sublist in l 
    # index1 indicates which sublist we check
    for index1, sublist in enumerate(l):
        # Go through every item in sublist 
        # index2 indicates which item we check
        for index2, item in enumerate(sublist):
            # append to result if we find a match
            if item == val:
                res.append([index1, index2])
    return res

With a sample list:

L = [[1, 2, 3], [4, 5, 6, 4, 3], [3, 3, 3]]

this returns:

find_index(L)
[[0, 2], [1, 4], [2, 0], [2, 1], [2, 2]]
Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
0

Consider returning a dict of indices using more_itertools.locate.

Code

import more_itertools as mit


def indices(iterable, item):
    """Return a dict of indices of all located items."""
    d = {}
    for i, sub in enumerate(iterable):
        val = list(mit.locate(sub, lambda x: x == item))
        if not val:
            continue
        d[i] = val

    return d

Demo

Given shallow, nested iterables:

indices([[1, 2, 3], [5, 6, 7]], 3)
# {0: [2]}

indices([[1, 2, 3], [5, 6, 7], [2, 3, 3]], 3)
# {0: [2], 2: [1, 2]}

Here multiple appearances are recorded.

pylang
  • 40,867
  • 14
  • 129
  • 121