Як перевірити, чи є щось (не) у списку в Python?
Найдешевше і найчитабельніше рішення - це використання in
оператора (або у вашому конкретному випадку not in
). Як зазначено в документації,
Оператори in
та not in
тест на членство. x in s
оцінює,
True
чи x
є членом s
, False
інакше. x not in s
повертає заперечення x in s
.
Крім того,
Оператор not in
визначено, що має обернене істинне значення in
.
y not in x
логічно те саме, що not y in x
.
Ось кілька прикладів:
'a' in [1, 2, 3]
# False
'c' in ['a', 'b', 'c']
# True
'a' not in [1, 2, 3]
# True
'c' not in ['a', 'b', 'c']
# False
Це також працює з кортежами, оскільки кортежі є гнучкими (як наслідок того, що вони також незмінні):
(1, 2) in [(3, 4), (1, 2)]
# True
Якщо об'єкт на RHS визначає __contains__()
метод, він in
буде внутрішньо викликати його, як зазначено в останньому абзаці розділу Порівняння в документах.
... in
і not in
, підтримуються типами, які є ітерабельними або реалізують
__contains__()
метод. Наприклад, ви могли (але не повинні) робити це:
[3, 2, 1].__contains__(1)
# True
in
коротке замикання, тому якщо ваш елемент знаходиться на початку списку, in
оцінюється швидше:
lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst # Expected to take longer time.
68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
Якщо ви хочете зробити більше, ніж просто перевірити, чи є предмет у списку, є варіанти:
list.index
може використовуватися для отримання індексу елемента. Якщо цього елемента не існує, ValueError
піднімається a .
list.count
можна використовувати, якщо ви хочете порахувати події.
Проблема XY: Ви вважали, що set
s?
Задайте собі ці питання:
- чи потрібно перевіряти, чи є предмет у списку більше одного разу?
- Чи виконується ця перевірка всередині циклу чи функція, яка викликається повторно?
- Чи є предметами, які ви зберігаєте у своєму списку, доступними? IOW, ти можеш подзвонити
hash
на них?
Якщо ви відповіли "так" на ці запитання, вам слід скористатись set
замість цього. in
Перевірка приналежності на list
е = О (п) складність. Це означає, що python повинен робити лінійну перевірку вашого списку, відвідуючи кожен елемент і порівнюючи його з пошуковим елементом. Якщо ви робите це неодноразово або якщо списки є великими, ця операція спричинить накладні витрати.
set
об'єкти, з іншого боку, мають свої значення для постійної перевірки членства в часі. Перевірка також проводиться за допомогою in
:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Якщо вам не шкода, що елемент, який ви шукаєте / не шукаєте, знаходиться в кінці списку, python відсканував список до кінця. Це видно з наведених нижче термінів:
l = list(range(100001))
s = set(l)
%timeit 100000 in l
%timeit 100000 in s
2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
Нагадування, це підходящий варіант, якщо елементи, які ви зберігаєте та шукаєте, є придатними. IOW, вони повинні або бути незмінними типами, або об'єктами, які реалізують __hash__
.
3 -1 > 0 and (4-1 , 5) not in []
⤇True
тому помилка не є одним з переваг оператора.