Как найти индекс последнего вхождения элемента питон
Перейти к содержимому

Как найти индекс последнего вхождения элемента питон

  • автор:

Python: проверить индекс элемента в списке

Списки полезны по-разному по сравнению с другими типами данных из-за их универсальности. В этой статье мы рассмотрим одну из самых распространенных операций со списками — поиск индекса элемента.

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

Использование Функции index()

Все операции, упомянутые в предыдущем абзаце, можно выполнить с помощью встроенной функции index() . Синтаксис этой функции:

index(element[, start[, end]])

Параметр element , естественно, представляет собой элемент который мы ищем. Параметры start и end являются необязательными и представляют диапазон индексов, в котором мы ищем element .

Значение по умолчанию для start — 0 (поиск с начала), а значение по умолчанию для end — это количество элементов в списке (поиск до конца списка).

Функция возвращает первую позицию element в списке, которую она могла найти, независимо от того, сколько равных элементов осталось после первого вхождения.

Нахождение первого появления элемента

Использование функции index() без установки каких-либо значений для start и end даст нам первое вхождение искомого element :

my_list = ['a', 'b', 'c', 'd', 'e', '1', '2', '3', 'b'] first_occurrence = my_list.index('b') print("First occurrence of 'b' in the list: ", first_occurrence) 

Что даст нам ожидаемый результат:

First occurrence of 'b' in the list: 1 
Поиск всех вхождений элемента

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

Например, предположим, что первое вхождение элемента в index 3 . Чтобы найти следующий, нам нужно будет продолжить поиск первого появления этого элемента после индекса 3 . Мы будем повторять этот процесс, меняя место начала поиска, пока мы найдем новые вхождения элемента:

my_list = ['b', 'a', 2, 'n', False, 'a', 'n', 'a'] all_occurrences = [] last_found_index = -1 element_found = True while element_found: try: last_found_index = my_list.index('a', last_found_index + 1) all_occurrences.append(last_found_index) except ValueError: element_found = False if len(all_occurrences) == 0: print("The element wasn't found in the list") else: print("The element was found at: " + str(all_occurrences)) 

Запуск этого кода даст нам:

The element was found at: [1, 5, 7] 

Здесь нам пришлось использовать блок try , так как функция index() выдает ошибку, когда не может найти указанный element в заданном диапазоне. Это может быть необычно для разработчиков, которые больше привыкли к другим языкам, поскольку такие функции обычно возвращают -1 / null , когда элемент не может быть найден.

Однако в Python мы должны быть осторожны и использовать блок try при использовании этой функции.

Другой, более изящный способ сделать то же самое — использовать понимание списка и полностью игнорировать функцию index() :

my_list = ['b', 'a', 2, 'n', False, 'a', 'n', 'a'] all_occurrences = [index for index, element in enumerate(my_list) if element == 'a'] print("The element was found at: " + str(all_occurrences)) 

Что даст нам тот же результат, что и раньше. У этого подхода есть дополнительное преимущество в том, что он не использует блок try .

Нахождение последнего появления элемента

Если вам нужно найти последнее вхождение элемента в списке, есть два подхода, которые вы можете использовать с функцией index() :

  1. Переверните список и найдите первое вхождение в перевернутом списке
  2. Просмотрите все вхождения элемента и отслеживайте только последнее вхождение

Что касается первого подхода, если бы мы знали первое вхождение element в обратном списке, мы могли бы найти позицию последнего вхождения в исходном. В частности, мы можем сделать это, вычтя reversed_list_index — 1 из длины исходного списка:

my_list = ['b', 'a', 2, 'n', False, 'a', 'n', 'a'] reversed_list_index = my_list[::-1].index('n') # or alteratively: # reversed_list_index2 = list(reversed(my_list)).index('n') original_list_index = len(my_list) - 1 - reversed_list_index print(original_list_index)

Что даст нам желаемый результат:

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

my_list = ['b', 'a', 2, 'n', False, 'a', 'n', 'a'] last_occurrence = -1 element_found = True while element_found: try: last_occurrence = my_list.index('n', last_occurrence + 1) except ValueError: element_found = False if last_occurrence == -1: print("The element wasn't found in the list") else: print("The last occurrence of the element is at: ", last_occurrence) 

Что даст нам тот же результат:

Вывод

Мы рассмотрели некоторые из наиболее распространенных способов использования функции index() и способы избежать ошибки в некоторых случаях.

Помните о потенциально необычном поведении функции index() , когда она выдает ошибку вместо возврата -1 / None , когда элемент не найден в списке.

Первое и последнее вхождение без метода count и циклов

Дана строка. Если в этой строке буква f встречается только один раз, выведите её индекс. Если она встречается два и более раз, выведите индекс её первого и последнего появления. Если буква f в данной строке не встречается, ничего не выводите. При решении этой задачи нельзя использовать метод count и циклы. это решение которое проходит проверку:

s = input() a = s.find('f') b = s.rfind('f') if a == -1: print() elif a == b: print(a) else: print(a, b) 

есть ли решения это задачи которые бы соответствовали требованиям

При решении этой задачи нельзя использовать метод count и циклы.

Отслеживать
52.4k 11 11 золотых знаков 110 110 серебряных знаков 312 312 бронзовых знаков
задан 3 фев 2018 в 6:47
35 1 1 золотой знак 1 1 серебряный знак 5 5 бронзовых знаков

7 ответов 7

Сортировка: Сброс на вариант по умолчанию

str.index

Чтобы распознать случаи: 0, 1, 2+ вхождений без явных циклов, s.count(‘f’) метода, очевидная альтернатива s.find() методу из вопроса — это s.index() :

#!/usr/bin/env python3 s = input() count = len(s) - len(s.replace('f', '')) if count == 0: pass elif count == 1: print(s.index('f')) else: # count > 1 print(s.index('f'), s.rindex('f')) 

try/except

Можно без явного if :

try: i = s.index('f') except ValueError: # count == 0 pass else: try: j = s.rindex('f', i+1) except ValueError: # count == 1 print(i) else: # count > 1 print(i, j) 

Рекурсия

Можно рекурсивный find() реализовать:

def find(char, s, i=0): return -1 if i == len(s) else i if char == s[i] else find(char, s, i+1) 

Тогда решение почти идентично варианту из вопроса (разница в том, что ничего не выводится для count==0 случая) :

s = input() i = find('f', s) j = len(s) - 1 - find('f', s[::-1]) # rfind('f', s) if i == -1: # count == 0 pass elif i == j: # count == 1 print(i) else: # count > 1 print(i, j) 

Итераторы

Можно find() даже без индексации и явного len(s) реализовать:

def find(char, s, i=0): it = iter(s) first = next(it, None) return -1 if first is None else i if first == char else find(char, it, i+1) 

Распаковка аргументов

Можно вообще не вызывать явно встроенные функции, опираясь на распаковку аргументов:

def find(char, s): def f(first, *rest, i=0): return i if first == char else -1 if not rest else f(*rest, i=i+1) return -1 if not s else f(*s) 

Связные списки

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

def reversed_as_llist(s): def f(first, *rest, llist=None): return f(*rest, llist=(first, llist)) if rest else (first, llist) return f(*s) if s else None 
>>> reversed_as_llist('abc') ('c', ('b', ('a', None))) 

Используя явные функции доступа:

first = lambda llist: llist[0] if llist else None rest = lambda llist: llist[1] if llist else None 

легко найти размер списка, реализовать поиск по аналогии с приведёнными решениями:

def llist_len(llist, size=0): return llist_len(rest(llist), size+1) if llist else size def llist_find(char, llist, i=0): return -1 if not llist else i if char == first(llist) else llist_find(char, rest(llist), i+1) 

Это позволяет определить rfind() без len(s) и индексации ( s[::-1] ):

def rfind(char, s): L = reversed_as_llist(s) i = llist_find(char, L) return i if i == -1 else llist_len(L) - 1 - i 

При желании, можно отказаться и от рекурсии с именованными функциями (к примеру, используя Y combinator) и даже не использовать явно числа (к примеру, заменяя на Church numerals).

heapq.nlargest

Если использовать встроенные функции, стандартную библиотеку, то есть множество решений, которые скрывают явный цикл и позволяют без .count(‘f’) обойтись:

import heapq indices = heapq.nlargest(2, range(len(s)), key=lambda i: s[i] == 'f') fs = ''.join(map(s.__getitem__, indices)) if fs == 'ff': # count == 2+ print(*indices) elif fs[:1] == 'f': # count == 1 print(indices[0]) # else print nothing # count == 0 

Как найти индекс элемента в списке, по частичному совпадению?

Как получить индексы всех элементов, содержащих имя Анна?

  • Вопрос задан более трёх лет назад
  • 1072 просмотра

Комментировать

Решения вопроса 1

SoreMix

soremix @SoreMix Куратор тега Python

Собственно, нужно перебрать все элементы из списка и проверять на вхождение в каждый элемент поисковой фразы с помощью in , если фраза входит в элемент — получаем индекс элемента через List.index(element)

search = 'Анна' indexes = [index_list.index(name) for name in index_list if search in name]

Ответ написан более трёх лет назад

Что делает функция индекс в Python?

Метод index() в Python помогает найти значение индекса элемента в последовательности. Он выдает наименьший возможный индекс указанного элемента. Если указанный элемент не существует, то возвращается ValueError.

sequence.index(x[, start[, end]]) 
  • sequence — это объект, элементы которого представляют собой некую индексированную последовательность (строка, список, кортеж). Каждый элемент последовательности имеет индекс — целое число, обозначающее его позицию в последовательности. Нумерация индексов начинается с 0 (нуля).
  • x — искомый элемент последовательности, чей наименьший индекс будет возвращен.
  • Необязательные аргументы start и end используются для ограничения поиска конкретной подпоследовательностью списка, путем задания среза. Возвращаемый индекс вычисляется относительно изначальной последовательности, а не среза, заданного start и end.
str_seq = 'aebcdef' #Последовательность в виде строки print(str_seq.index('e')) # => 1 print(str_seq.index('e', 2)) # => 5 print(str_seq.index('k')) # => ValueError: substring not found lst_seq = ['a', 'e', 'b', 'c', 'd', 'e', 'f'] #Последовательность в виде списка print(lst_seq.index('b')) # => 2 print(lst_seq.index('k')) # => ValueError: 'k' is not in list tup_seq = ('a', 'e', 'b', 'c', 'd', 'e', 'f') #Последовательность в виде кортежа print(tup_seq.index('a')) # => 0 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *