Як отримати позицію товару в списку?


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

і досить niftily ми можемо призначити цю змінну і використовувати її звідти ...

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

І щоб подумати, я писав FORTRAN.


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

15
Я припускаю, що ви маєте на увазі "одну літеру" і, чесно кажучи, довша назва в цьому прикладі не мала б більше інформаційного змісту.
Чарлі Мартін

2
Дякую за чудову відповідь. Я думаю, що коментар @ nailer може стосуватися того, що ви використовуєте 'я' у двох різних контекстах в одному рядку в прикладі генератора; один усередині розуміння, а інший повторювати його. Я знаю, що це відкинуло мене на секунду.
Браун

1
@CharlieMartin Ви використовуєте 'i' для індексу, а не елемент у відповідності до однієї загальної конвенції для змінних одного символу. Названня індексу «індекс» та елемента «позиція» усуне двозначність. Крім того, ви відповідаєте батькові, який використовував "елемент" і "позиція", і радимо не зайвим чином перейменовувати у своїй відповіді частини оригінального коду.
mikemaccana

1
Супер синтаксис: o) Ви можете легко отримати параметр командного рядка. Нехай є масив аргументів: 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 замість діапазону, як вимагається (див. коментарі).


замінити діапазон () на xrange () - range () створює список, xrange () створює ітератор. xrange () використовує у waaaay менше пам'яті, а вхідний дзвінок швидше.
gnud

2
Я погоджуюсь на великі списки програм python 2. Зауважте, що 'range' все одно буде працювати в python 3 (і працюватиме як xrange IIRC). 'xrange' йде шляхом динозаврів.
jakber

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% швидше, ніж цей код. (Я замінив ваше твердження про друк на вихідний виклик. Додайте дзвінок)
Деестан,

Я також робив кілька тестів із розмірами списку 100000 випадкових значень між 1 і 100. Код, який я написав, у деяких випадках був удвічі швидшим. Жоден час тестування не можна порівняти із заявою плаката (звичайно, вони повинні перевірити себе). Прошу вибачення, якщо моя думка шкодила цій посаді.

0

Я думаю, що може бути корисним використовувати метод curselection () з бібліотеки Tkinter:

from Tkinter import * 
listbox.curselection()

Цей метод працює на віджетах listbox list 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.