Вопрос-Ответ

How to check if all elements of a list match a condition?

Как проверить, соответствуют ли все элементы списка условию?

У меня есть список, который содержит множество вложенных списков по 3 элемента в каждом, например:

my_list = [["a", "b", 0], ["c", "d", 0], ["e", "f", 0], .....]

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

def check(list_):
for item in list_:
if item[2] == 0:
return True
return False

Общий алгоритм выполняет цикл до тех пор, пока это условие выполняется, и устанавливает некоторые флаги на каждой итерации:

while check(my_list):
for item in my_list:
if condition:
item[2] = 1
else:
do_sth()

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

Как я могу упростить или ускорить код?


Смотрите также Pythonic способ проверки выполнения условия для любого элемента списка, чтобы проверить условие для любого элемента. Имейте в виду, что проверки "any" и "all" связаны по закону Де Моргана, так же как связаны "или" и "и".

В существующих ответах здесь используется встроенная функция all для выполнения итерации. Смотрите Как работают все функции Python? для объяснения all и его аналога, any.

Если вы хотите проверить условие "находится в другом контейнере", см. Как проверить, все ли следующие элементы находятся в списке? и его аналог, как проверить, есть ли в списке один из следующих элементов?. Использование any и all будет работать, но возможны более эффективные решения.

Переведено автоматически
Ответ 1

Лучший ответ здесь - использовать all(), который является встроенным для данной ситуации. Мы объединяем это с выражением генератора, чтобы получить желаемый результат чисто и эффективно. Например:

>>> items = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
>>> all(flag == 0 for (_, _, flag) in items)
True
>>> items = [[1, 2, 0], [1, 2, 1], [1, 2, 0]]
>>> all(flag == 0 for (_, _, flag) in items)
False

Обратите внимание, что all(flag == 0 for (_, _, flag) in items) это напрямую эквивалентно all(item[2] == 0 for item in items), просто в этом случае читать немного приятнее.

И, для примера фильтра, понимание списка (конечно, вы могли бы использовать выражение генератора, где это уместно):

>>> [x for x in items if x[2] == 0]
[[1, 2, 0], [1, 2, 0]]

Если вы хотите проверить, что хотя бы один элемент равен 0, лучшим вариантом будет использовать any() который более удобочитаем:

>>> any(flag == 0 for (_, _, flag) in items)
True
Ответ 2

Если вы хотите проверить, не нарушает ли какой-либо элемент в списке условие, используйте all:

if all([x[2] == 0 for x in lista]):
# Will run if all elements in the list has x[2] = 0 (use not to invert if necessary)

Чтобы удалить все несоответствующие элементы, используйте filter

# Will remove all elements where x[2] is 0
listb = filter(lambda x: x[2] != 0, listb)
Ответ 3

Вы могли бы использовать функцию itertools takewhile подобным образом, она остановится, как только будет выполнено условие, которое завершается ошибкой вашего оператора. Противоположным методом будет dropwhile

for x in itertools.takewhile(lambda x: x[2] == 0, list)
print x
Ответ 4

этот способ немного более гибкий, чем использование all():

my_list = [[1, 2, 0], [1, 2, 0], [1, 2, 0]]
all_zeros = False if False in [x[2] == 0 for x in my_list] else True
any_zeros = True if True in [x[2] == 0 for x in my_list] else False

или более кратко:

all_zeros = not False in [x[2] == 0 for x in my_list]
any_zeros = 0 in [x[2] for x in my_list]
2024-01-27 06:16 python list