Как получить позицию элемента в списке?


169

Я перебираю список и хочу распечатать индекс элемента, если он удовлетворяет определенному условию. Как бы я это сделал?

Пример:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position

Ответы:


280

Хммм. Здесь был ответ с пониманием списка, но он исчез.

Вот:

 [i for i,x in enumerate(testlist) if x == 1]

Пример:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

Обновить:

Хорошо, вы хотите выражение генератора, у нас будет выражение генератора. Вот снова понимание списка в цикле for:

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

Теперь мы построим генератор ...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

и достаточно ловко, мы можем присвоить это переменной и использовать ее оттуда ...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

И подумать я раньше писал на Фортране.


6
После 25 лет сомнений в функциональном программировании, я думаю, я наконец-то понял. понимание списка да бомба.
Чарли Мартин

15
Я предполагаю, что вы имеете в виду «одну букву», и, честно говоря, более длинное имя в этом примере не будет больше информационного содержания.
Чарли Мартин

2
Спасибо за отличный ответ. Я думаю, что комментарий @ nailer может относиться к тому факту, что вы используете 'i' в двух разных контекстах в одной строке в примере генератора; один внутри понимания, а другой перебирать его. Я знаю, это отбросило меня на секунду.
Браун

1
@CharlieMartin Вы используете 'i' для индекса, а не элемент в соответствии с одним общим соглашением для односимвольных переменных. Обозначение индекса index и item item устранит неоднозначность. Кроме того, вы отвечаете родителю, который использовал «item» и «position», и это хороший способ не переименовывать части исходного кода в вашем ответе.
mikemaccana

1
Супер синтаксис: о) Вы можете легко получить параметр командной строки. Пусть есть массив аргументов: args = ['x', '-p1', 'v1', '-p2', 'v2']. Затем команда args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]возвращается'v1'
Теодор Кейнштейн

170

Как насчет следующего?

print testlist.index(element)

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

if element in testlist:
    print testlist.index(element)

или

print(testlist.index(element) if element in testlist else None)

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

try:
    print testlist.index(element)
except ValueError:
    pass

5
вместо того, чтобы тестировать перед доступом, вы также можете просто попробоватьValueError
kratenko

Я думаю, что он хочет найти все вхождения, вы, кажется, даете только первое.
TFV

@ tfv Я не понимаю, как вы можете прийти к такому выводу, поскольку в вопросе говорится «пункт», а не «элементы».
MMJ

40

Используйте перечислять:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange вместо диапазона, как требуется (см. комментарии).


replace range () на xrange () - range () создает список, xrange () создает итератор. xrange () использует меньше памяти, а исходный вызов быстрее.
gnud

2
Я согласен на большие списки в программах Python 2. Обратите внимание, что 'range' все еще будет работать в Python 3 (и работать как xrange IIRC). «xrange» идет по пути динозавров.
Джекбер

2
Обновление: xrangeразвращено в Python 3.x, так как новое range- староеxrange
tim-oh

5

Вот еще один способ сделать это:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"



1

Если ваш список стал достаточно большим, и вы ожидали найти значение только в небольшом количестве индексов, учтите, что этот код может выполняться намного быстрее, поскольку вам не нужно повторять каждое значение в списке.

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

Если вы ожидаете много найти значение, вам, вероятно, следует просто добавить «индекс» в список и распечатать список в конце, чтобы сэкономить время на итерацию.


Я сделал несколько тестов времени. Техника понимания списка работает на 38% быстрее, чем этот код. (Я заменил ваше заявление на печать вызовом outputlist.append)
Дестан

Я также провел несколько тестов с размерами списка 100000 случайных значений от 1 до 100. Код, который я написал, в некоторых случаях был в два раза быстрее. Ни одно временное тестирование не сравнимо с приложением автора (конечно, они должны проверить себя). Я прошу прощения, если мое мнение было вредным для этого поста.

0

Я думаю, что было бы полезно использовать метод curselection () из библиотеки Tkinter:

from Tkinter import * 
listbox.curselection()

Этот метод работает с виджетами списка Tkinter, поэтому вам нужно создать один из них вместо списка.

Это вернет позицию как это:

('0',) (хотя более поздние версии Tkinter могут вместо этого возвращать список целых)

Который для первой позиции и номер будет меняться в зависимости от позиции элемента.

Для получения дополнительной информации см. Эту страницу: http://effbot.org/tkinterbook/listbox.htm

Приветствую.


1
Интересная идея. Поскольку для этого требуется импортировать всю библиотеку Tkinter, это не самый эффективный способ решения проблемы.
seaotternerd

3
Это такой неэффективный и извилистый путь, что я бы сказал, что это неправильный ответ, даже если он несколько решает вопрос.

Этот ответ не имеет ничего общего с вопросом.
Коди Пирсолл

0

Зачем усложнять вещи?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

0

Просто, чтобы проиллюстрировать полный пример вместе с input_listкоторым есть searies1(пример: input_list [0]), в котором вы хотите выполнить поиск series2(пример: input_list [1]) и получить индексы серии2, если она существует в серии1.

Примечание: вы certain conditionбудете идти в лямбда-выражении, если условия просты

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

вывод:

[0, 2, 6]

-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

Я думаю, что это именно то, что вы хотите. ;-) 'id' всегда будет индексом значений в списке.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.