Проверьте несколько условий в списках (цикл для)

#python #python-3.x

#питон #python-3.x #python

Вопрос:

У меня проблема с проверкой нескольких условий одновременно.

 import itertools

def repeats(input1, input2):
    return [int(dz) for dz in input1 if int(dz) in input2]

n_combs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]

filters = [[[1, 2, 3, 6, 7, 8, 11, 12, 16, 17, 21, 22], [5]], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [7]], [[20, 21, 22, 23, 24], [2]]]

combinacoes = itertools.combinations(n_combs, 15)

for comb in combinacoes:
    for filtro, maxx in filters:

        if len(repeats(filtro, comb)) in maxx:
            print(comb)
  

В принципе, мне нужна комбинация для печати только в том случае, если:

  • содержать 5 элементы из этого списка: [1, 2, 3, 6, 7, 8, 11, 12, 16, 17, 21, 22]
  • содержать 7 элементы из этого списка: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
  • содержать 2 элементы из этого списка: [20, 21, 22, 23, 24]

Приведенный выше код не выполняет 3 проверки одновременно, и это то, что мне нужно.

Ответ №1:

Я думаю, что ваш цикл работает должным образом только в том случае, filters что последний элемент не соответствует указанным вами условиям. Отредактируйте его, чтобы включить меньшие числа, как я сделал ниже. Кроме того, я уменьшил количество элементов в n_combs , чтобы мой ответ стал понятным. Это потому, что перебор более 3 миллионов записей в 25 combination 15 не очень хорошая идея для демонстрационных целей. Попробуйте запустить отредактированную версию ниже, и вы увидите, что я говорю.

 import itertools

def repeats(input1, input2):
    return [int(dz) for dz in input1 if int(dz) in input2]

n_combs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

filters = [[[1, 2, 3, 6, 7, 8, 11, 12, 16, 17, 21, 22], [5]], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [7]], [[2, 4, 7,9], [2]]]

combinacoes = itertools.combinations(n_combs, 15)

for comb in combinacoes:
    for filtro, maxx in filters:

        if len(repeats(filtro, comb)) in maxx:
            print(comb, maxx)
  

Дайте мне знать, решит ли это вашу проблему.

Комментарии:

1. Я думаю, вы не поняли. Код не выполняет 3 проверки одновременно. Рассмотрите возможность использования этого вместо того, что я передал filters = [[[1, 2, 3, 6, 7, 8, 11, 12, 16, 17, 21, 22], [1, 3, 4] 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [3, 4]

Ответ №2:

Я предполагаю, что вы хотите применить произвольное количество тестов к некоторому значению.

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

 def iterable_contains_1(value):
    return 1 in value

def iterable_contains_2(value):
    return 2 in value

validators = [iterable_contains_1, iterable_contains_2]
  

Затем вы можете вызвать все свои проверки:

 for item in ([1, 2, 3], [2, 3, 4], [1, 3, 4], [3, 4, 5]):
    if all(validator(item) for validator in validators):
        print('do something with', item)
  

Это будет печатать только do something with [1, 2, 3] поскольку это единственный список, проходящий оба теста.

[править]

Я думаю, вы ищете set .

 def validator1(iterable):
    return len(
        set(iterable).intersection(
            [1, 2, 3, 6, 7, 8, 11, 12, 16, 17, 21, 22]
        )) >= 5

def validator2(iterable):
    return len(
        set(iterable).intersection(
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
        )) >= 7

def validator3(iterable):
    return len(
        set(iterable).intersection(
            [20, 21, 22, 23, 24]
        )) >= 2
  

Комментарии:

1. Я не понимаю, как ваш код может решить мою проблему. Не могли бы вы использовать мои проблемные данные в качестве примера? Помня, что я использовал только 2 фильтра / списка только для облегчения ввода в эксплуатацию. Учтите, что их сотни

2. Этот код не подходит, потому что у меня есть тысячи списков, которые нужно протестировать, и создание функции для каждого из них неверно.

3. Как грубо! Очевидно, что вы можете абстрагировать логику (подсказка, единственное различие между функциями — это список и количество совпадений). Имейте в виду, что stackoverflow не является бесплатным сервисом для кодирования. Волонтеры здесь пытаются вам помочь, а вы платите им жесткой критикой?

4. Извините, если я вас обидел, это не входило в мои намерения. Я просто хотел сказать, что ваш код не соответствует тому, который мне нужен. Большое вам спасибо за вашу готовность помочь, на самом деле. Спасибо!

Ответ №3:

Я нашел решение:

 import itertools

def repeats(input1, input2):
    return [int(dz) for dz in input1 if int(dz) in input2]

n_combs = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]

filters = [[[1, 2, 3, 6, 7, 8, 11, 12, 16, 17, 21, 22], [5]], [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [7]], [[20, 21, 22, 23, 24], [2]]]

combinacoes = itertools.combinations(n_combs, 15)

for comb in combinacoes:
    if all([len(repeats(filtro, comb)) in qtd for filtro, qtd in filters]):
        print(comb)
  

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

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