Как найти все числа в списке python

Create a generator

Generators are fast and use a tiny memory footprint. They give you flexibility in how you use the result.

def indices(iter, val):
    """Generator: Returns all indices of val in iter
    Raises a ValueError if no val does not occur in iter
    Passes on the AttributeError if iter does not have an index method (e.g. is a set)
    """
    i = -1
    NotFound = False
    while not NotFound:
        try:
            i = iter.index(val, i+1)
        except ValueError:
            NotFound = True
        else:
            yield i
    if i == -1:
        raise ValueError("No occurrences of {v} in {i}".format(v = val, i = iter))

The above code can be use to create a list of the indices: list(indices(input,value)); use them as dictionary keys: dict(indices(input,value)); sum them: sum(indices(input,value)); in a for loop for index_ in indices(input,value):; …etc… without creating an interim list/tuple or similar.

In a for loop you will get your next index back when you call for it, without waiting for all the others to be calculated first. That means: if you break out of the loop for some reason you save the time needed to find indices you never needed.

How it works

  • Call .index on the input iter to find the next occurrence of
    val
  • Use the second parameter to .index to start at the point
    after the last found occurrence
  • Yield the index
  • Repeat until index raises a ValueError

Alternative versions

I tried four different versions for flow control; two EAFP (using try - except) and two TBYL (with a logical test in the while statement):

  1. «WhileTrueBreak»: while True:except ValueError: break. Surprisingly, this was usually a touch slower than option 2 and (IMV) less readable
  2. «WhileErrFalse»: Using a bool variable err to identify when a ValueError is raised. This is generally the fastest and more readable than 1
  3. «RemainingSlice»: Check whether val is in the remaining part of the input using slicing: while val in iter[i:]. Unsurprisingly, this does not scale well
  4. «LastOccurrence»: Check first where the last occurrence is, keep going while i < last

The overall performance differences between 1,2 and 4 are negligible, so it comes down to personal style and preference. Given that .index uses ValueError to let you know it didn’t find anything, rather than e.g. returning None, an EAFP-approach seems fitting to me.

Here are the 4 code variants and results from timeit (in milliseconds) for different lengths of input and sparsity of matches

@version("WhileTrueBreak", versions)
def indices2(iter, val):
    i = -1
    while True:
        try:
            i = iter.index(val, i+1)
        except ValueError:
            break
        else:
            yield i

@version("WhileErrFalse", versions)
def indices5(iter, val):
    i = -1
    err = False
    while not err:
        try:
            i = iter.index(val, i+1)
        except ValueError:
            err = True
        else:
            yield i

@version("RemainingSlice", versions)
def indices1(iter, val):
    i = 0
    while val in iter[i:]:
        i = iter.index(val, i)
        yield i
        i += 1

@version("LastOccurrence", versions)
def indices4(iter,val):
    i = 0
    last = len(iter) - tuple(reversed(iter)).index(val)
    while i < last:
        i = iter.index(val, i)
        yield i
        i += 1
Length: 100, Ocurrences: 4.0%
{'WhileTrueBreak': 0.0074799987487494946, 'WhileErrFalse': 0.006440002471208572, 'RemainingSlice': 0.01221001148223877, 'LastOccurrence': 0.00801000278443098}
Length: 1000, Ocurrences: 1.2%
{'WhileTrueBreak': 0.03101000329479575, 'WhileErrFalse': 0.0278000021353364, 'RemainingSlice': 0.08278000168502331, 'LastOccurrence': 0.03986000083386898}
Length: 10000, Ocurrences: 2.05%
{'WhileTrueBreak': 0.18062000162899494, 'WhileErrFalse': 0.1810499932616949, 'RemainingSlice': 2.9145700042136014, 'LastOccurrence': 0.2049500006251037}
Length: 100000, Ocurrences: 1.977%
{'WhileTrueBreak': 1.9361200043931603, 'WhileErrFalse': 1.7280600033700466, 'RemainingSlice': 254.4725100044161, 'LastOccurrence': 1.9101499929092824}
Length: 100000, Ocurrences: 9.873%
{'WhileTrueBreak': 2.832529996521771, 'WhileErrFalse': 2.9984100023284554, 'RemainingSlice': 1132.4922299943864, 'LastOccurrence': 2.6660699979402125}
Length: 100000, Ocurrences: 25.058%
{'WhileTrueBreak': 5.119729996658862, 'WhileErrFalse': 5.2082200068980455, 'RemainingSlice': 2443.0577100021765, 'LastOccurrence': 4.75954000139609}
Length: 100000, Ocurrences: 49.698%
{'WhileTrueBreak': 9.372120001353323, 'WhileErrFalse': 8.447749994229525, 'RemainingSlice': 5042.717969999649, 'LastOccurrence': 8.050809998530895}

На чтение 4 мин Просмотров 5.6к. Опубликовано 03.03.2023

Содержание

  1. Введение
  2. Поиск методом count
  3. Поиск при помощи цикла for
  4. Поиск с использованием оператора in
  5. В одну строку
  6. Поиск с помощью лямбда функции
  7. Поиск с помощью функции any()
  8. Заключение

Введение

В ходе статьи рассмотрим 5 способов поиска элемента в списке Python.

Поиск методом count

Метод count() возвращает вхождение указанного элемента в последовательность. Создадим список разных цветов, чтобы в нём производить поиск:

colors = ['black', 'yellow', 'grey', 'brown']

Зададим условие, что если в списке colors присутствует элемент ‘yellow’, то в консоль будет выведено сообщение, что элемент присутствует. Если же условие не сработало, то сработает else, и будет выведена надпись, что элемента отсутствует в списке:

colors = ['black', 'yellow', 'grey', 'brown']

if colors.count('yellow'):
    print('Элемент присутствует в списке!')
else:
    print('Элемент отсутствует в списке!')

# Вывод: Элемент присутствует в списке!

Поиск при помощи цикла for

Создадим цикл, в котором будем перебирать элементы из списка colors. Внутри цикла зададим условие, что если во время итерации color приняла значение ‘yellow’, то элемент присутствует:

colors = ['black', 'yellow', 'grey', 'brown']

for color in colors:
    if color == 'yellow':
         print('Элемент присутствует в списке!')

# Вывод: Элемент присутствует в списке!

Поиск с использованием оператора in

Оператор in предназначен для проверки наличия элемента в последовательности, и возвращает либо True, либо False.

Зададим условие, в котором если ‘yellow’ присутствует в списке, то выводится соответствующее сообщение:

colors = ['black', 'yellow', 'grey', 'brown']

if 'yellow' in colors:
    print('Элемент присутствует в списке!')
else:
    print('Элемент отсутствует в списке!')

# Вывод: Элемент присутствует в списке!

В одну строку

Также можно найти элемент в списке при помощи оператора in всего в одну строку:

colors = ['black', 'yellow', 'grey', 'brown']

print('Элемент присутствует в списке!') if 'yellow' in colors else print('Элемент отсутствует в списке!')

# Вывод: Элемент присутствует в списке!

Или можно ещё вот так:

colors = ['black', 'yellow', 'grey', 'brown']

if 'yellow' in colors: print('Элемент присутствует в списке!')

# Вывод: Элемент присутствует в списке!

Поиск с помощью лямбда функции

В переменную filtering будет сохранён итоговый результат. Обернём результат в список (list()), т.к. метода filter() возвращает объект filter. Отфильтруем все элементы списка, и оставим только искомый, если он конечно присутствует:

colors = ['black', 'yellow', 'grey', 'brown']

filtering = list(filter(lambda x: 'yellow' in x, colors))

Итак, если искомый элемент находился в списке, то он сохранился в переменную filtering. Создадим условие, что если переменная filtering не пустая, то выведем сообщение о присутствии элемента в списке. Иначе – отсутствии:

colors = ['black', 'yellow', 'grey', 'brown']

filtering = list(filter(lambda x: 'yellow' in x, colors))

if filtering:
    print('Элемент присутствует в списке!')
else:
    print('Элемент отсутствует в списке!')

# Вывод: Элемент присутствует в списке!

Поиск с помощью функции any()

Функция any принимает в качестве аргумента итерабельный объект, и возвращает True, если хотя бы один элемент равен True, иначе будет возвращено False.

Создадим условие, что если функция any() вернёт True, то элемент присутствует:

colors = ['black', 'yellow', 'grey', 'brown']

if any(color in 'yellow' for color in colors):
    print('Элемент присутствует в списке!')
else:
    print('Элемент отсутствует в списке!')

# Вывод: Элемент присутствует в списке!

Внутри функции any() при помощи цикла производится проверка присутствия элемента в списке.

Заключение

В ходе статьи мы с Вами разобрали целых 5 способов поиска элемента в списке Python. Надеюсь Вам понравилась статья, желаю удачи и успехов! 🙂

Время чтения 3 мин.

Существует несколько способов проверки наличия элемента в списке в Python:

  1. Использование метода index() для поиска индекса элемента в списке.
  2. Использование оператора in для проверки наличия элемента в списке.
  3. Использование метода count() для подсчета количества вхождений элемента.
  4. Использование функции any().
  5. Функция filter() создает новый список элементов на основе условий.
  6. Применение цикла for.

Содержание

  1. Способ 1: Использование метода index()
  2. Способ 2: Использование «оператора in»
  3. Способ 3: Использование функции count()
  4. Синтаксис
  5. Пример
  6. Способ 4: использование понимания списка с any()
  7. Способ 5: Использование метода filter()
  8. Способ 6: Использование цикла for

Способ 1: Использование метода index()

Чтобы найти элемент в списке Python, вы можете использовать метод list index(). Список index() — это встроенный метод, который ищет элемент в списке и возвращает его индекс.

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

Индекс в Python начинается с 0, а не с 1. Таким образом, через индекс мы можем найти позицию элемента в списке.

streaming = [‘netflix’, ‘hulu’, ‘disney+’, ‘appletv+’]

index = streaming.index(‘disney+’)

print(‘The index of disney+ is:’, index)

Выход

The index of disney+ is: 2

Метод list.index() принимает единственный аргумент, элемент, и возвращает его позицию в списке.

Способ 2: Использование «оператора in»

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

main_list = [11, 21, 19, 46]

if 19 in main_list:

  print(«Element is in the list»)

else:

  print(«Element is not in the list»)

Выход

Вы можете видеть, что элемент «19» находится в списке. Вот почему оператор in возвращает True.

Если вы проверите элемент «50», то оператор in вернет False и выполнит оператор else.

Способ 3: Использование функции count()

Метод list.count() возвращает количество вхождений данного элемента в списке.

Синтаксис

Метод count() принимает единственный элемент аргумента: элемент, который будет подсчитан.

Пример

main_list = [11, 21, 19, 46]

count = main_list.count(21)

if count > 0:

  print(«Element is in the list»)

else:

  print(«Element is not in the list»)

Выход

Мы подсчитываем элемент «21», используя список в этой функции example.count(), и если он больше 0, это означает, что элемент существует; в противном случае это не так.

Способ 4: использование понимания списка с any()

Any() — это встроенная функция Python, которая возвращает True, если какой-либо элемент в итерируемом объекте имеет значение True. В противном случае возвращается False.

main_list = [11, 21, 19, 46]

output = any(item in main_list for item in main_list if item == 22)

print(str(bool(output)))

Выход

Вы можете видеть, что в списке нет «22». Таким образом, нахождение «22» в списке вернет False функцией any(). Если функция any() возвращает True, элемент в списке существует.

Способ 5: Использование метода filter()

Метод filter() перебирает элементы списка, применяя функцию к каждому из них.

Функция filter() возвращает итератор, который перебирает элементы, когда функция возвращает значение True.

main_list = [11, 21, 19, 46]

filtered = filter(lambda element: element == 19, main_list)

print(list(filtered))

Выход

В этом примере мы используем функцию filter(), которая принимает функцию и перечисляет ее в качестве аргумента.

Мы использовали лямбда-функцию, чтобы проверить, совпадает ли входной элемент с любым элементом из списка, и если это так, он вернет итератор. Чтобы преобразовать итератор в список в Python, используйте функцию list().

Мы использовали функцию list() для преобразования итератора, возвращаемого функцией filter(), в список.

Способ 6: Использование цикла for

Вы можете узнать, находится ли элемент в списке, используя цикл for в Python.

main_list = [11, 21, 19, 46]

for i in main_list:

  if(i == 46):

    print(«Element Exists»)

Выход

В этом примере мы прошли список элемент за элементом, используя цикл for, и если элемент списка совпадает с входным элементом, он напечатает «Element exists».

In this tutorial, you’ll learn how to use the Python list index method to find the index (or indices) of an item in a list. The method replicates the behavior of the indexOf() method in many other languages, such as JavaScript. Being able to work with Python lists is an important skill for a Pythonista of any skill level. We’ll cover how to find a single item, multiple items, and items meetings a single condition.

By the end of this tutorial, you’ll have learned:

  • How the Python list.index() method works
  • How to find a single item’s index in a list
  • How to find the indices of all items in a list
  • How to find the indices of items matching a condition
  • How to use alternative methods like list comprehensions to find the index of an item in a list

Python List Index Method Explained

The Python list.index() method returns the index of the item specified in the list. The method will return only the first instance of that item. It will raise a ValueError is that item is not present in the list.

Let’s take a look at the syntax of the index() method:

# The list.index() Method Explained
list.index(
    element,    # The element to search for
    start,      # The index to start searching at
    end         # The index to end searching at
)

Let’s break these parameters down a little further:

  • element= represents the element to be search for in the list
  • start= is an optional parameter that indicates which index position to start searching from
  • end= is an optional parameter that indicates which index position to search up to

The method returns the index of the given element if it exists. Keep in mind, it will only return the first index. Additionally, if an item doesn’t exist, a ValueError will be raised.

In the next section, you’ll learn how to use the .index() method.

Find the Index Position of an Item in a Python List

Let’s take a look at how the Python list.index() method works. In this example, we’ll search for the index position of an item we know is in the list.

Let’s imagine we have a list of the websites we open up in the morning and we want to know at which points we opened 'datagy'.

# Finding the index of an item in a list
a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']
print(a_list.index('datagy'))

# Returns: 0

We can see that the word 'datagy' was in the first index position. We can see that the word 'twitter' appears more than once in the list. In the next section, you’ll learn how to find every index position of an item.

Finding All Indices of an Item in a Python List

In the section above, you learned that the list.index() method only returns the first index of an item in a list. In many cases, however, you’ll want to know the index positions of all items in a list that match a condition.

Unfortunately, Python doesn’t provide an easy method to do this. However, we can make use of incredibly versatile enumerate() function and a for-loop to do this. The enumerate function iterates of an item and returns both the index position and the value.

Let’s see how we can find all the index positions of an item in a list using a for loop and the enumerate() function:

# Finding all indices of an item in a list
def find_indices(search_list, search_item):
    indices = []
    for (index, item) in enumerate(search_list):
        if item == search_item:
            indices.append(index)

    return indices

a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']
print(find_indices(a_list, 'twitter'))

# Returns: [1, 3]

Let’s break down what we did here:

  1. We defined a function, find_indices(), that takes two arguments: the list to search and the item to find
  2. The function instantiates an empty list to store any index position it finds
  3. The function then loops over the index and item in the result of the enumerate() function
  4. For each item, the function evaludates if the item is equal to the search term. If it is, the index is appended to the list
  5. Finally, this list is returned

We can also shorten this list for a more compact version by using a Python list comprehension. Let’s see what this looks like:

# A shortened function to return all indices of an item in a list
def find_indices(search_list, search_item):
    return [index for (index, item) in enumerate(search_list) if item == search_item]

a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']
print(find_indices(a_list, 'twitter'))

# Returns: [1, 3]

One of the perks of both these functions is that when an item doesn’t exist in a list, the function will simply return an empty list, rather than raising an error.

Find the Last Index Position of an Item in a Python List

In this section, you’ll learn how to find the last index position of an item in a list. There are different ways to approach this. Depending on the size of your list, you may want to choose one approach over the other.

For smaller lists, let’s use this simpler approach:

# Finding the last index position of an item in a list
def find_last_index(search_list, search_item):
    return len(search_list) - 1 - search_list[::-1].index(search_item)

a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']

print(find_last_index(a_list, 'twitter'))

# Returns: 3

In this approach, the function subtracts the following values:

  • len(search_list) returns the length of the list
  • 1, since indices start at 0
  • The .index() of the reversed list

There are two main problems with this approach:

  1. If an item doesn’t exist, an ValueError will be raised
  2. The function makes a copy of the list. This can be fine for smaller lists, but for larger lists this approach may be computationally expensive.

Let’s take a look at another approach that loops over the list in reverse order. This saves the trouble of duplicating the list:

# A less simple, but more memory efficient way of finding the last index of an item
def find_last_index(search_list, search_item):
    i = len(search_list) - 1
    while i >= 0:
        if search_list[i] == search_item:
            return i
        else:
            i -= 1
            
a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']

print(find_last_index(a_list, 'twitter'))

# Returns: 3

In the example above we loop over the list in reverse, by starting at the last index. We then evaluate if that item is equal to the search term. If it is we return the index position and the loop ends. Otherwise, we decrement the value by 1 using the augmented assignment operator.

Index of an Element Not Present in a Python List

By default, the Python list.index() method will raise a ValueError if an item is not present in a list. Let’s see what this looks like. We’ll search for the term 'pinterest' in our list:

# Searching for an item that doesn't exist
a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']

print(a_list.index('pinterest'))

# Raises: ValueError: 'pinterest' is not in list

When Python raises this error, the entire program stops. We can work around this by nesting it in a try-except block.

Let’s see how we can handle this error:

# Handling an error when an item doesn't exist
a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']

try:
    print(a_list.index('pinterest'))
except ValueError:
    print("Item doesn't exist!")

# Returns: Item doesn't exist!

Working with List Index Method Parameters

The Python list.index() method also provides two additional parameters, start= and stop=. These parameters, respectively, indicate the positions at which to start and stop searching.

Let’s say that we wanted to start searching at the second index and stop at the sixth, we could write:

# Using Start and Stop Parameters in list.index()
a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']

print(a_list.index('twitter', 2, 6))

# Returns: 3

By instructing the method to start at index 2, the method skips over the first instance of the string 'twitter'.

Finding All Indices of Items Matching a Condition

In this final section, we’ll explore how to find the index positions of all items that match a condition. Let’s say, for example, that we wanted to find all the index positions of items that contain the letter 'y'. We could use emulate the approach above where we find the index position of all items. However, we’ll add in an extra condition to our check:

# Finding Indices of Items Matching a Condition
def find_indices(search_list, search_item):
    return [index for (index, item) in enumerate(search_list) if search_item in item]


a_list = ['datagy', 'twitter', 'facebook', 'twitter', 'tiktok', 'youtube']
print(find_indices(a_list, 'y'))

# Returns:
# [0, 5]

The main difference in this function to the one shared above is that we evaluate on a more “fuzzy” condition.

Conclusion

In this tutorial, you learned how to use the index list method in Python. You learned how the method works and how to use it to find the index position of a search term. You also learned how to find the index positions of items that exist more than once, as well as finding the last index position of an item.

Finally, you learned how to handle errors when an item doesn’t exist as well as how to find the indices of items that match a condition.

Additional Resources

To learn more about related topics, check out the tutorials below:

  • Python Lists: A Complete Overview
  • Python Zip Lists – Zip Two or More Lists in Python
  • Python IndexError: List Index Out of Range Error Explained
  • Python List Index: Official Documentation

Получение индекса для строк: str.index (), str.rindex() и str.find(), str.rfind()

String также имеет index метод , но и более продвинутые варианты и дополнительное str.find.Для обоих из них есть дополнительный обратный метод.

astring = 'Hello on StackOverflow'
astring.index('o')  # 4
astring.rindex('o') # 20

astring.find('o')   # 4
astring.rfind('o')  # 20

 

Разница между index / rindex и find / rfind это то , что происходит , если подстрока не найдена в строке:

astring.index('q') # ValueError: substring not found
astring.find('q')  # -1
 

Все эти методы позволяют начальный и конечный индексы:

astring.index('o', 5)    # 6
astring.index('o', 6)    # 6 - start is inclusive
astring.index('o', 5, 7) # 6
astring.index('o', 5, 6) #  - end is not inclusive
 

ValueError: подстрока не найдена

astring.rindex('o', 20) # 20 
astring.rindex('o', 19) # 20 - still from left to right

astring.rindex('o', 4, 7) # 6 

В поисках элемента

Все встроенные в коллекции в Python реализовать способ проверить членство элемента с использованием in. Список

alist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5 in alist   # True
10 in alist  # False

 

Кортеж

atuple =('0', '1', '2', '3', '4')
4 in atuple    # False
'4' in atuple  # True

 

строка

astring = 'i am a string'
'a' in astring   # True
'am' in astring  # True
'I' in astring   # False

 

Задавать

aset = {(10, 10), (20, 20), (30, 30)}
(10, 10) in aset  # True
10 in aset        # False

 

Dict

dict немного особенный: нормальный in проверяет только ключи. Если вы хотите , чтобы искать в значении , которые необходимо указать. То же самое , если вы хотите найти пар ключ-значение.

adict = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}
1 in adict                 # True   - implicitly searches in keys
'a' in adict               # False
2 in adict.keys()          # True   - explicitly searches in keys
'a' in adict.values()      # True   - explicitly searches in values
(0, 'a') in adict.items()  # True   - explicitly searches key/value pairs 

Получение списка индексов и кортежей: list.index(), tuple.index()

list и tuple имеют index -метода получить позицию элемента:

alist = [10, 16, 26, 5, 2, 19, 105, 26]
# search for 16 in the list
alist.index(16) # 1
alist[1]        # 16

alist.index(15)

 

Ошибка значения: 15 отсутствует в списке

Но возвращает только позицию первого найденного элемента:

atuple = (10, 16, 26, 5, 2, 19, 105, 26)
atuple.index(26)   # 2
atuple[2]          # 26
atuple[7]          # 26 - is also 26! 

Поиск ключа(ей) по значению в dict

dict не имеет встроенный метода для поиска значения или ключа , потому что словари являются упорядоченными. Вы можете создать функцию, которая получает ключ (или ключи) для указанного значения:

def getKeysForValue(dictionary, value):
    foundkeys = []
    for keys in dictionary:
        if dictionary[key] == value:
            foundkeys.append(key)
    return foundkeys

 

Это также может быть записано как эквивалентное понимание списка:

def getKeysForValueComp(dictionary, value): 
    return [key for key in dictionary if dictionary[key] == value]

 

Если вам нужен только один найденный ключ:

def getOneKeyForValue(dictionary, value):
    return next(key for key in dictionary if dictionary[key] == value)

 

Первые две функции возвращает list всех keys , которые имеют определенное значение:

adict = {'a': 10, 'b': 20, 'c': 10}
getKeysForValue(adict, 10)     # ['c', 'a'] - order is random could as well be ['a', 'c']
getKeysForValueComp(adict, 10) # ['c', 'a'] - dito
getKeysForValueComp(adict, 20) # ['b']
getKeysForValueComp(adict, 25) # []

 

Другой вернет только один ключ:

getOneKeyForValue(adict, 10)   # 'c'  - depending on the circumstances this could also be 'a'
getOneKeyForValue(adict, 20)   # 'b'

 

и поднять StopIterationException , если значение не в dict :

getOneKeyForValue(adict, 25)
 

StopIteration

Получение индекса для отсортированных последовательностей: bisect.bisect_left()

Отсортированные последовательности позволяют использовать более быстрый поиск алгоритмов: bisect.bisect_left() [1]:

import bisect

def index_sorted(sorted_seq, value):
    """Locate the leftmost value exactly equal to x or raise a ValueError"""
    i = bisect.bisect_left(sorted_seq, value)
    if i != len(sorted_seq) and sorted_seq[i] == value:
        return i
    raise ValueError

alist = [i for i in range(1, 100000, 3)] # Sorted list from 1 to 100000 with step 3
index_sorted(alist, 97285) # 32428
index_sorted(alist, 4)     # 1
index_sorted(alist, 97286)
 

ValueError

Для очень больших отсортированных последовательностей выигрыш в скорости может быть достаточно высоким. В случае первого поиска примерно в 500 раз быстрее:

%timeit index_sorted(alist, 97285)
# 100000 loops, best of 3: 3 µs per loop
%timeit alist.index(97285)
# 1000 loops, best of 3: 1.58 ms per loop

 

Хотя это немного медленнее, если элемент является одним из самых первых:

%timeit index_sorted(alist, 4)
# 100000 loops, best of 3: 2.98 µs per loop
%timeit alist.index(4)
# 1000000 loops, best of 3: 580 ns per loop

 

Поиск вложенных последовательностей

Поиск во вложенных последовательностях , как в list из tuple требует такого подхода , как поиск ключей для значений в dict , но нуждается в пользовательских функциях.

Индекс самой внешней последовательности, если значение было найдено в последовательности:

def outer_index(nested_sequence, value):
    return next(index for index, inner in enumerate(nested_sequence) 
                      for item in inner 
                      if item == value)

alist_of_tuples = [(4, 5, 6), (3, 1, 'a'), (7, 0, 4.3)]
outer_index(alist_of_tuples, 'a')  # 1
outer_index(alist_of_tuples, 4.3)  # 2

 

или индекс внешней и внутренней последовательности:

def outer_inner_index(nested_sequence, value):
    return next((oindex, iindex) for oindex, inner in enumerate(nested_sequence) 
                                 for iindex, item in enumerate(inner) 
                                 if item == value)

outer_inner_index(alist_of_tuples, 'a') # (1, 2)
alist_of_tuples[1][2]  # 'a'

outer_inner_index(alist_of_tuples, 7)   # (2, 0)
alist_of_tuples[2][0]  # 7

 

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

Поиск в пользовательских классах: __contains__ и __iter__

Для того, чтобы разрешить использование in пользовательских классах класса должен либо предоставить магический метод __contains__ или, если это невозможно, в __iter__ -метод.

Предположим , у вас есть класс , содержащий list из list s:

class ListList:
    def __init__(self, value):
        self.value = value
        # Create a set of all values for fast access
        self.setofvalues = set(item for sublist in self.value for item in sublist)

    def __iter__(self):
        print('Using __iter__.')
        # A generator over all sublist elements
        return (item for sublist in self.value for item in sublist)

    def __contains__(self, value):
        print('Using __contains__.')
        # Just lookup if the value is in the set
        return value in self.setofvalues

        # Even without the set you could use the iter method for the contains-check:
        # return any(item == value for item in iter(self))

 

Использование тестирования членства возможно при использовании in :

a = ListList([[1,1,1],[0,1,1],[1,5,1]])
10 in a    # False
# Prints: Using __contains__.
5 in a     # True
# Prints: Using __contains__.

 

даже после удаления __contains__ метода:

del ListList.__contains__
5 in a     # True
# Prints: Using __iter__.

 

Примечание: зацикливание in (как for i in a ) всегда будет использовать __iter__ даже если класс реализует __contains__ метод.

Понравилась статья? Поделить с друзьями:
  • Как составить формулу горения вещества
  • Х образные ноги у подростка как исправить упражнениями
  • Как исправить кожу ног
  • Как найти индекс показателя
  • Как найти файл в папке delphi