2013-05-28 3 views
0

Предположим, например, у вас есть списокСписок Постижение Индексация

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']] 

и другой список

b = ['phone', 'lost'] 

И вы хотите, чтобы найти список c, который содержит индексы строк в a (мышление a как 2D-матрица), чей первый столбец является значением в b. Так в этом случае

c = [1, 2] 

Я пытался использовать следующие списковых

c = [i if a[i][0] in b for i in range(0, 1)] 
c = [i if a[i][0] in b] 

Но оба они были признаны недействительными синтаксиса.

ответ

4

Использование enumerate():

c = [i for i, v in enumerate(a) if v[0] in b] 

enumerate() дает вам как индекс и значение из итерации вы передаете Обратите внимание, что тест if идет в конце;. списочные должны быть записаны в том же порядке, что вы будете использовать, когда гнездящиеся петли:

c = [] 
for i, v in enumerate(a): 
    if v[0] in b: 
     c.append(i) 

Вы действительно хотите сделать b набор:

b = set(b) 

сделать членство тестирования O (1) постоянная в отличие от линейного теста времени O (n) против списка.

Демо:

>>> a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']] 
>>> b = {'phone', 'lost'} # set literal 
>>> [i for i, v in enumerate(a) if v[0] in b] 
[1, 2] 
+0

@ Джон: Просто потому, что OP имеет ошибку совсем по-одному, не означает, что вам нужно изменить ту же самую ошибку в моем ответе. :-P –

+0

Собирался, потом подумал об этом, затем отвлекся, поэтому отбросил его, что тогда не было на самом деле отброшенным;) [один из тех дней :(] –

+0

Спасибо Martijn! – rwolst

0

Сначала массив начало от 0. Таким образом, с должно быть:

c=[1,2] 

, если вам нужно сделать это с помощью сжатия списка решение может быть:

c=[pos for pos, val_a in enumerate(a) for val_b_to_check in val_a if val_b_to_check in b ] 
+0

Это испытание для * всех * значений в строке, OP хотел проверить только для элемента * first *. –

+0

Если вы хотите протестировать все значения в каждой строке, использование набора пересечений будет быстрее (если 'b' является набором): '[i для i, v в перечислении (a), если b & v]' –

+0

Вам нужно выполнить кастинг для установки также на v. [i для i, v в перечислении (a), если b & set (v)] – aparo

0

Вы можете использовать Numpy для этого:

>>> import numpy as np 
>>> a = np.array([['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]) 
>>> b = np.array(['phone', 'lost']) 
>>> np.in1d(a[:,0],b) 
array([False, True, True], dtype=bool) 

Или, если вы хотите, индексы:

>>> np.where(np.in1d(a[:,0],b))[0].tolist() 
[1, 2] 
Смежные вопросы