简体   繁体   中英

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?

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)]

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
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

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.

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

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

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]

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM