2013-04-08 3 views
3

У меня есть список списков строк, например:Python, получить индекс из списка списков

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

Учитывая строку, я хочу его индекс в л. Экспериментируя с NumPy, это то, что я закончил с:

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' 

Это терпит неудачу для яблока и стул, получая IndexError. Кроме того, это просто выглядит плохо для меня. Есть ли еще более подходящие для этого?

ответ

3

Возвращает список кортежей, содержащих (внешний индексный список, внутренний индексного списка), спроектированный таким образом, что деталь вы ищете может быть в нескольких внутренние списки:

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

Я бы создать словарь для отображения элементов в их индексы:

>>> 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 хорош для создания индекса, но это не обязательно. Конечно, это будет наиболее эффективным, если вы сможете создать индекс один раз, а затем повторно использовать его для последующих поисков.

0

Один из способов использовать 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 
1

Если вы хотите использовать NumPy, вам не нужно свернуть свой собственный:

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 
0

В вашей строке, которая вычисляет i, у вас уже есть ответ, если вы применяете argwhere к всему списку, а не к каждому подписок. Нет необходимости снова искать j.

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

Это будет возврат в нуль первого появления строки, которую вы ищете.

Кроме того, вы можете подумать, как этот метод влияет на сложность проблемы. Этот метод будет перебирать все элементы вашего списка, поэтому стоимость выполнения увеличивается по мере увеличения списка. Итак, если количество тестовых строк, которые вы пытаетесь найти в списке, также увеличивается, вам может понадобиться подумать об использовании словаря для создания таблицы поиска один раз, а затем последующие поиски тестовых строк будут дешевле.

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 
0

Чтобы получить индекс списка списка в 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]