list списке - Поиск индекса элемента с указанием списка, содержащего его в Python




последний замена (23)

Для списка ["foo", "bar", "baz"] и элемента в списке "bar" , как мне получить его индекс (1) в Python?


Answers

Поиск индекса элемента x в списке L :

idx = L.index(x) if (x in L) else -1

a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']

index() возвращает первый индекс значения!

| индекс(...)
| L.index (значение, [start, [stop]]) -> integer - возвращает первый индекс значения

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])

name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

Это учитывается, если строка также не указана в списке, если она отсутствует в списке, тогда location = -1


>>> ["foo", "bar", "baz"].index("bar")
1

Ссылки: Структуры данных> Подробнее о списках

Предостережения

Обратите внимание, что хотя это, пожалуй, самый чистый способ ответить на заданный вопрос , index является довольно слабым компонентом API-интерфейса list , и я не могу вспомнить последний раз, когда я использовал его в гневе. В комментариях было указано, что, поскольку этот ответ в значительной степени упоминается, его следует сделать более полным. Ниже list.index некоторые оговорки о list.index . Вероятно, стоит сначала взглянуть на документную строку:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

Линейная временная сложность в длине списка

Вызов index проверяет каждый элемент списка по порядку, пока не найдет совпадение. Если ваш список длинный, и вы не знаете, где именно находится в списке, этот поиск может стать узким местом. В этом случае вы должны рассмотреть другую структуру данных. Обратите внимание, что если вы знаете, где найти совпадение, вы можете дать index подсказку. Например, в этом фрагменте l.index(999_999, 999_990, 1_000_000) примерно на пять порядков быстрее, чем прямой l.index(999_999) , поскольку первый должен искать только 10 записей, в то время как последний ищет миллион:

>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514

Возвращает только индекс первого совпадения к его аргументу

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

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2

В большинстве мест, где я когда-то использовал index , я теперь использую выражение для составления списка или генератор, потому что они более обобщаемы. Поэтому, если вы планируете обратиться к index , взгляните на эти превосходные функции python.

Выбрасывает, если элемент отсутствует в списке

Вызов index приводит к ValueError если элемент отсутствует.

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: 2 is not in list

Если элемент может отсутствовать в списке, вы должны либо

  1. Сначала проверьте его в item in my_list (чистый, читаемый подход) или
  2. Оберните index вызов в блок try/except который ловит ValueError (возможно, быстрее, по крайней мере, когда список поиска длинный, и элемент обычно присутствует.)

Поскольку списки Python основаны на нуле, мы можем использовать встроенную функцию zip следующим образом:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

где «haystack» - это список, о котором идет речь, и «игла» - это предмет, который нужно искать.

(Примечание: здесь мы итерируем с помощью i, чтобы получить индексы, но если нам нужно сосредоточиться на элементах, мы можем переключиться на j.)


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

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1

Большинство ответов объясняют, как найти один индекс , но их методы не возвращают несколько индексов, если элемент находится в списке несколько раз. Использовать enumerate() :

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

Функция index() возвращает только первое вхождение, а enumerate() возвращает все вхождения.

Как понимание списка:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

Вот еще одно небольшое решение с itertools.count() (это почти тот же подход, что и перечисление):

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

Это более эффективно для больших списков, чем использование enumerate() :

$ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop

А сейчас нечто соверешнно другое...

... как подтверждение существования элемента перед тем, как получить индекс. Самое приятное в этом подходе - функция всегда возвращает список индексов - даже если это пустой список. Он также работает со строками.

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    retval = []
    last = 0
    while val in l[last:]:
            i = l[last:].index(val)
            retval.append(last + i)
            last += i + 1   
    return retval

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

При вставке в интерактивное окно python:

Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(the_list, val):
...     """Always returns a list containing the indices of val in the_list"""
...     retval = []
...     last = 0
...     while val in the_list[last:]:
...             i = the_list[last:].index(val)
...             retval.append(last + i)
...             last += i + 1   
...     return retval
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

Обновить

После еще одного года развития python с хедз-ап, я немного смущен своим первоначальным ответом, поэтому, чтобы установить запись прямо, можно, конечно, использовать приведенный выше код; тем не менее, гораздо более идиоматический способ получить такое же поведение будет заключаться в использовании понимания списка, а также функции enumerate ().

Что-то вроде этого:

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    return [index for index, value in enumerate(l) if value == val]

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

Который при вставке в интерактивное окно python дает:

Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(l, val):
...     """Always returns a list containing the indices of val in the_list"""
...     return [index for index, value in enumerate(l) if value == val]
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

И теперь, рассмотрев этот вопрос и все ответы, я понимаю, что это именно то, что предложил в своем более раннем ответе . В то время, когда я первоначально ответил на этот вопрос, я даже не видел этого ответа, потому что я этого не понимал. Я надеюсь, что мой несколько более подробный пример поможет понять.

Если одна строка кода выше все еще не имеет для вас смысла, я настоятельно рекомендую вам «понимание списков python Google» и занять несколько минут, чтобы ознакомиться. Это всего лишь одна из многих мощных функций, которые радуют использование Python для разработки кода.


Чтобы получить все индексы:

 indexes = [i for i,x in enumerate(xs) if x == 'foo']

Все индексы с функцией zip :

get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]

print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')

Если производительность вызывает озабоченность:

В многочисленных ответах упоминается, что встроенный метод метода list.index(item) является алгоритмом O (n). Это нормально, если вам нужно выполнить это один раз. Но если вам нужно обращаться к индексам элементов несколько раз, имеет смысл сначала создать словарь (O (n)) пар item-index, а затем получить доступ к индексу в O (1) каждый раз, когда вам нужно Это.

Если вы уверены, что элементы в списке никогда не повторяются, вы можете легко:

myList = ["foo", "bar", "baz"]

# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))

# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.

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

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Lookup
myDict["foo"] # Returns [0, 4]

Поиск индекса элемента с указанием списка, содержащего его в Python

Для списка ["foo", "bar", "baz"] и элемента в списке "bar" , какой самый чистый способ получить свой индекс (1) в Python?

Ну, конечно, есть индексный метод, который возвращает индекс первого вхождения:

>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1

Существует несколько проблем с этим методом:

  • если значение отсутствует в списке, вы получите ValueError
  • если в списке больше одного значения, вы получаете только индекс для первого

Нет значений

Если значение может отсутствовать, вам нужно поймать ValueError .

Вы можете сделать это с помощью многоразового определения следующим образом:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

И используйте его вот так:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

И недостатком этого является то, что у вас, вероятно, будет проверка, если возвращаемое значение is или is not None:

result = index(a_list, value)
if result is not None:
    do_something(result)

В списке более одного значения

Если у вас может быть больше случаев, вы не получите полную информацию с list.index :

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

Вы можете перечислить в список понимание индексов:

>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

Если у вас нет вхождений, вы можете проверить это с помощью логической проверки результата или просто ничего не делать, если вы зацикливаете результаты:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

Улучшение сбора данных с помощью панд

Если у вас есть панды, вы можете легко получить эту информацию с помощью объекта Series:

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

Проверка сравнения вернет ряд булевых:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

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

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

Если вам нужны только индексы, атрибут index возвращает ряд целых чисел:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

И если вы хотите, чтобы они были в списке или кортеже, просто передайте их конструктору:

>>> list(series[series == 'bar'].index)
[1, 3]

Да, вы могли бы использовать представление списка с перечислением тоже, но это не так уж и изящно, на мой взгляд, вы делаете тесты для равенства в Python, вместо того чтобы позволить встроенный код, написанный на C, обрабатывать его:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

Это проблема XY ?

Проблема XY спрашивает о вашем попытке решения, а не о вашей реальной проблеме.

Почему, по-вашему, вам нужен индекс, заданный элементом в списке?

Если вы уже знаете это значение, почему вам все равно, где он находится в списке?

Если значения нет, ловить значение ValueError довольно многословно, и я предпочитаю избегать этого.

Я обычно итерации по списку в любом случае, поэтому я обычно буду держать указатель на любую интересную информацию, получая индекс с перечислением.

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

Я не помню, что мне нужен list.index . Тем не менее, я просмотрел стандартную библиотеку Python, и я вижу для этого отличные возможности.

В нем используется много, много вариантов для idlelib , для графического интерфейса и синтаксического анализа текста.

Модуль keyword использует его для поиска маркеров комментариев в модуле для автоматического восстановления списка ключевых слов в нем с помощью метапрограммирования.

В Lib / mailbox.py кажется, что он использует его как упорядоченное отображение:

key_list[key_list.index(old)] = new

а также

del key_list[key_list.index(key)]

В Lib / http / cookiejar.py, похоже, используется для получения следующего месяца:

mon = MONTHS_LOWER.index(mon.lower())+1

В Lib / tarfile.py аналогично distutils, чтобы получить фрагмент до элемента:

members = members[:members.index(tarinfo)]

В Lib / pickletools.py:

numtopop = before.index(markobject)

Кажется, что эти обычаи имеют общий характер: они работают в списках ограниченных размеров (важно из-за времени поиска O (n) для list.index ), и они в основном используются при разборе (и пользовательский интерфейс в случае Idle).

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


Как указано в @TerryA, многие ответы обсуждают, как найти один индекс.

more_itertools - это сторонняя библиотека с инструментами для поиска нескольких индексов внутри итерации.

Дано

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

Код

Найти индексы нескольких наблюдений:

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

Проверьте несколько элементов:

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

См. Также дополнительные параметры с more_itertools.locate . Установите через more_itertools .


Другой вариант

>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
...     indices.append(a.index(b,offset))
...     offset = indices[-1]+1
... 
>>> indices
[0, 3]
>>> 

Это более функциональный ответ.

list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

Более общая форма:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))

Метод python index() выдает ошибку, если элемент не найден, что отстой!

Поэтому вместо этого вы можете сделать его похожим на indexOf() JavaScript, которая возвращает -1 если элемент не был найден:

    try:
        index = array.index('search_keyword')
    except ValueError:
        index = -1

Для тех, кто приходит с другого языка, как я, возможно, с помощью простого цикла, его легче понять и использовать:

mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)

Я благодарен за то, что именно делает enumerate? , Это помогло мне понять.


Если вам нужны все индексы, вы можете использовать NumPy :

import numpy as np

array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)

Это ясное, читаемое решение.


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

 eg: li=[10,20,30] # here need to get index of 20 means
     li.index(20) # will work properly because 20 is not repeated

если его повторные средства он даст вам только первый индекс

Если вам нужно получить весь индекс, в котором находится элемент, значит

eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3) 

получить, что вам нужно сделать это, как

 li=[10,20,30,20,40, 50, 10]
 [i for i, e in enumerate(li) if e == 20]

то вы получите список индексов как o / p, например [1,3]


Одна вещь, которая действительно полезна в изучении Python, заключается в использовании интерактивной функции справки:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

который часто приведет вас к методу, который вы ищете.


Вариант ответа от FMc и user7177 даст dict, который может вернуть все индексы для любой записи:

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

Вы также можете использовать это как один лайнер для получения всех индексов для одной записи. Нет никаких гарантий эффективности, хотя я использовал set (a), чтобы уменьшить количество вызовов лямбда.


В Python вы можете объединить два массива совместимых измерений с помощью этой команды

numpy.concatenate([a,b])






python list