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

Я написал пакет Python, целью которого является решение этой проблемы:

pip install fuzzymatcher

Здесь вы можете найти repo здесь и docs здесь .

Базовое использование:

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

from fuzzymatcher import link_table, left join

# Columns to match on from df_left
left_on = ["fname", "mname", "lname",  "dob"]

# Columns to match on from df_right
right_on = ["name", "middlename", "surname", "date"]

# The link table potentially contains several matches for each record
fuzzymatcher.link_table(df_left, df_right, left_on, right_on)

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

fuzzymatcher.fuzzy_left_join(df_left, df_right, left_on, right_on)

2785
задан kmario23 3 May 2019 в 08:20
поделиться

3 ответа

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

Ссылка: Структуры данных> Больше в Списках

Протесты следуют

Примечание, которое, в то время как это - возможно, самый чистый способ ответить на вопрос , как спросили , index, довольно слабый компонент list API, и я не могу помнить прошлый раз, когда я использовал его в гневе. На это указали мне в комментариях, что, потому что на этот ответ в большой степени ссылаются, это должно быть сделано больше завершенным. Некоторые протесты [приблизительно 117] следуют. Это, вероятно, стоит первоначально смотреть на docstring для него:

>>> 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

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

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

>>> [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, я теперь, использует понимание списка или выражение генератора, потому что они более generalizable. Таким образом, если Вы рассматриваете достижение для [1 114], смотрите на эти превосходные функции Python.

Броски, если элемент, не существующий в списке

, А звонят в [1 115] результаты в ValueError если объект не существующий.

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

, Если объект не мог бы присутствовать в списке, Вы должны любой

  1. Проверка на него сначала с [1 117] (чистый, читаемый подход), или
  2. Обертка эти index вызов в try/except блок, который ловит ValueError (вероятно, быстрее, по крайней мере, то, когда список для поиска длинен, и объект, обычно присутствует.)
3996
ответ дан Alex Taylor 3 May 2019 в 08:20
поделиться

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

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

class list(object)
 ...

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

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

852
ответ дан davidavr 3 May 2019 в 08:20
поделиться
  • 1
    @Sekar I' m боящийся! Won' t это позволяют другим людям от моего ISP обрабатывать содержание XAMPP? – Santosh Kumar 2 February 2013 в 06:49

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

def findInList(List, item):
   try:
      return List.index(item)
   except ValueError:
      return -1

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

, По-моему, предполагая, что что-то пошло не так, как надо, если объект не найден, лучше использовать try - except, но с пользовательским сообщением об ошибке, и таким образом это не сделает отладку тяжелее, и при этом возвращаемое значение не будет иметь значения:

# python 3.x

class itemNotFoundInListError(Exception): 
    pass

def findInList(List, item):
   try:
      return List.index(item)
   except ValueError:
      raise itemNotFoundInListError(f"List `{List}` does not contain `{item}.`")
0
ответ дан 22 November 2019 в 19:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: