user2258896
user2258896

Reputation: 53

Python, get index from list of lists

I have a list of lists of strings, like this:

l = [['apple','banana','kiwi'],['chair','table','spoon']]

Given a string, I want its index in l. Experimenting with numpy, this is what I ended up with:

import numpy as np
l = [['apple','banana','kiwi'],['chair','table','spoon']]
def ind(s):
    i = [i for i in range(len(l)) if np.argwhere(np.array(l[i]) == s)][0]
    j = np.argwhere(np.array(l[i]) == s)[0][0]
    return i, j
s = ['apple','banana','kiwi','chair','table','spoon']
for val in s:
    try:
        print val, ind(val)
    except IndexError:
        print 'oops'

This fails for apple and chair, getting an indexerror. Also, this just looks bad to me. Is there some better approch to doing this?

Upvotes: 5

Views: 25065

Answers (8)

Carsten
Carsten

Reputation: 3048

This solution will find all occurrences of the string you're searching for:

l = [['apple','banana','kiwi','apple'],['chair','table','spoon']]

def findItem(theList, item):
       return [(i, j) for i, line in enumerate(theList)
               for j, char in enumerate(line) if char == item]

findItem(l, 'apple') # [(0, 0), (0, 3)]
findItem(l, 'spoon') # [(1, 2)]

Upvotes: 0

Mohammed Agboola
Mohammed Agboola

Reputation: 37

To get index of list of list in python:

theList = [[1,2,3], [4,5,6], [7,8,9]]
for i in range(len(theList)):
    if 5 in theList(i):
        print("[{0}][{1}]".format(i, theList[i].index(5))) #[1][1]

Upvotes: 0

KP.
KP.

Reputation: 1267

In your line that computes i, you already have the answer if you apply argwhere to the entire list, rather than each sublist. There is no need to search again for j.

def ind(s):
    match = np.argwhere(np.array(l == s))
    if match:
        i, j = match[0]
    else:
        return -1, -1

This is will return the indeces of the first occurence of the string you're searching for.

Also, you might consider how this method is impacted as the complexity of the problem increases. This method will iterate over every element of your list, so the runtime cost increases as the list becomes bigger. So, if the number of test strings you're trying to find in the list also increases, you might want to think about using a dictionary to create a lookup table once, then subsequent searches for test strings are cheaper.

def make_lookup(search_list):
    lookup_table = {}
    for i, sublist in enumerate(list):
        for j, word in enumerate(sublist):
            lookup_table[word] = (i, j)
    return lookup_table

lookup_table = make_lookup(l)

def ind(s):
    if s in lookup_table:
        return lookup_table[s]
    else:
        return -1, -1

Upvotes: 0

mtadd
mtadd

Reputation: 2555

If you want to use numpy, you don't need to roll your own:

import numpy as np
l = np.array([['apple','banana','kiwi'],['chair','table','spoon']])
s = ['apple','banana','kiwi','chair','table','spoon']

for a in s:
    arg = np.argwhere(l==a)
    print a, arg, tuple(arg[0]) if len(arg) else None

Upvotes: 1

Manny D
Manny D

Reputation: 20744

Returns a list of tuples containing (outer list index, inner list index), designed such that the item you're looking for can be in multiple inner lists:

l = [['apple','banana','kiwi'],['chair','table','spoon']]
def findItem(theList, item):
   return [(ind, theList[ind].index(item)) for ind in xrange(len(theList)) if item in theList[ind]]

findItem(l, 'apple') # [(0, 0)]
findItem(l, 'spoon') # [(1, 2)]

Upvotes: 4

zwol
zwol

Reputation: 140846

One way is to make use of enumerate:

l = [['apple','banana','kiwi'],['chair','table','spoon']]
s = ['apple','banana','kiwi','chair','table','spoon']

for a in s:
    for i, ll in enumerate(l):
        for j, b in enumerate(ll):
            if a == b:
                print a, i, j

Upvotes: 0

mgilson
mgilson

Reputation: 310227

I'd create a dictionary to map the items to their indices:

>>> import numpy as np
>>> l = [['apple','banana','kiwi'],['chair','table','spoon']]
>>> a = np.array(l,dtype=object)
>>> a
array([[apple, banana, kiwi],
       [chair, table, spoon]], dtype=object)
>>> d = {s:idx for (idx),s in np.ndenumerate(a)}
>>> d['apple']
(0, 0)
>>> d['chair']
(1, 0)

numpy + ndenumerate is nice for creating the index, but it's definitely not necessary. Of course, this is going to be most efficient if you can create the index once and then reuse it for subsequent searches.

Upvotes: 0

Rushy Panchal
Rushy Panchal

Reputation: 17552

l = [['apple','banana','kiwi'],['chair','table','spoon']]
def search(lst, item):
    for i in range(len(lst)):
        part = lst[i]
        for j in range(len(part)):
            if part[j] == item: return (i, j)
    return None

Upvotes: 0

Related Questions