2015-06-05 3 views
1

Попытка найти индекс подписок с элементом. Я не знаю, как определить проблему точно (может быть, поэтому я упускается его в руководстве), однако моя проблема такова:Найти индекс подписок в списке

list1 = [[1,2],[3,4],[7,8,9]] 

Я хочу, чтобы найти первый суб-лист в list1 где появляется 7 (в этом случае индекс равен 2, но lll может быть очень длинным). (Это будет так, что каждый номер будет отображаться только в одном под-списке - или вообще не будет. Также это только списки целых чисел) I.e. функция как

spam = My_find(list1, 7) 

даст спам = 2 я мог бы попробовать зацикливание, чтобы сделать логическое значение, индексирование

[7 in x for x in lll] 

, а затем .index найти «истинный» - (по Most efficient way to get indexposition of a sublist in a nested list) Однако безусловно, необходимость создания нового булевского списка действительно неэффективна.

Мой код начинается с того, что список1 относительно невелик, однако он продолжает наращивать (в конечном итоге, будет 1 миллион номеров, расположенных примерно в 5000 sub-lis ts of list1

Любые мысли?

ответ

4

Я мог бы попробовать зацикливание, чтобы сделать логическое значение, индексирования

[7 in x for x in lll] 

, а затем .index найти «истинный» ... Тем не менее, конечно, того, чтобы построить новый булев список действительно неэффективен

Вы здесь довольно близко.

Во-первых, чтобы избежать создания списка, используйте выражение генератора вместо понимания списка, просто заменив [] на ().

sevens = (7 in x for x in lll) 

Но как сделать эквивалент .index, когда у вас есть произвольное Iterable, вместо списка? Вы можете использовать enumerate, чтобы связать каждое значение с его индексом, а затем просто отфильтровать не-семерки с filter или dropwhile или другим выражением генератора, то next даст вам индекс и значение первого True.

Например:

indexed_sevens = enumerate(sevens) 
seven_indexes = (index for index, value in indexed_sevens if value) 
first_seven_index = next(seven_indexes) 

Вы, конечно, можете свернуть все это в одно большое выражение, если вы хотите.

И, если вы думаете об этом, вам действительно не нужно это начальное выражение вообще; Вы можете сделать это в более позднем этапе фильтрации:

first_seven_index = next(index for index, value in enumerate(lll) if 7 in value) 

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

+0

Спасибо - очень ясно и точно, что я хотел. – CastleH

Смежные вопросы