Разделение списка на множество списков с условиями - PullRequest
0 голосов
/ 23 февраля 2019

У меня такой код для создания 4 списков из одного с моими условиями.Это разделение зависит от знака элементов списков.Как я хочу получить список со всеми положительными, список со списками, где первые элементы положительны, а вторые отрицательны и т. Д ... И все комбинации, как это.С помощью фильтра легко создать 4 списка, если все списки содержат только 2 элемента.

vals=[(0, 0), (0, 1), (0, -1), (1, 0), (1, 1), (1, -1), (-1, 0), (-1, 1), (-1, -1)]
new_f=list(filter(lambda x:x[0]>=0,vals))
new_f=list(filter(lambda x:x[1]>=0,new_f))
print(new_f)
new_f=list(filter(lambda x:x[0]<=0,vals))
new_f=list(filter(lambda x:x[1]>=0,new_f))
print(new_f)
new_f=list(filter(lambda x:x[0]>=0,vals))
new_f=list(filter(lambda x:x[1]<=0,new_f))
print(new_f)
new_f=list(filter(lambda x:x[0]<=0,vals))
new_f=list(filter(lambda x:x[1]<=0,new_f))
print(new_f)

Вот мой вывод:

[(0, 0), (0, 1), (1, 0), (1, 1)]
[(0, 0), (0, 1), (-1, 0), (-1, 1)]
[(0, 0), (0, -1), (1, 0), (1, -1)]
[(0, 0), (0, -1), (-1, 0), (-1, -1)]

Но если длина моих элементов равна 3 илиболее того, что я могу сделать, чтобы не написать все условия (будет 2 ** 3 ситуации и 2 ** 4 ситуации для len = 4) Например, вот мой ввод для n = 3 и пример ситуации, когда я хочуОтфильтруйте это как "нет отрицательных" и "первый-отрицательный-другой, не отрицательный"

vals=[(0, 0, 0), (0, 0, 1), (0, 0, -1), (0, 1, 0), (0, 1, 1), (0, 1, -1), (0, -1, 0), (0, -1, 1), (0, -1, -1), (1, 0, 0), (1, 0, 1), (1, 0, -1), (1, 1, 0), (1, 1, 1), (1, 1, -1), (1, -1, 0), (1, -1, 1), (1, -1, -1), (-1, 0, 0), (-1, 0, 1), (-1, 0, -1), (-1, 1, 0), (-1, 1, 1), (-1, 1, -1), (-1, -1, 0), (-1, -1, 1), (-1, -1, -1)]
new_f=list(filter(lambda x:x[0]>=0,vals))
new_f=list(filter(lambda x:x[1]>=0,new_f))
new_f=list(filter(lambda x:x[2]>=0,new_f))
print(new_f)
new_f=list(filter(lambda x:x[0]<=0,vals))
new_f=list(filter(lambda x:x[1]>=0,new_f))
new_f=list(filter(lambda x:x[2]>=0,new_f))
print(new_f)

Вот вывод:

[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (-1, 0, 0), (-1, 0, 1), (-1, 1, 0), (-1, 1, 1)]

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

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Вы можете использовать itertools.product над двумя функциями фильтра с repeat размерами кортежей на вашем входе, затем zip фильтр функционирует с отдельными элементами в каждом кортеже и выводить кортеж только если все фильтрыудовлетворены:

[[t for t in vals if all(f(i) for (f, i) in zip(filters, t))] for filters in product(((0).__le__, (0).__ge__), repeat=len(vals[0]))]

, так что с учетом вашего образца ввода:

vals = [(0, 0, 0), (0, 0, 1), (0, 0, -1), (0, 1, 0), (0, 1, 1), (0, 1, -1), (0, -1, 0), (0, -1, 1), (0, -1, -1), (1, 0, 0), (1, 0, 1), (1, 0, -1), (1, 1, 0), (1, 1, 1), (1, 1, -1), (1, -1, 0), (1, -1, 1), (1, -1, -1), (-1, 0, 0), (-1, 0, 1), (-1, 0, -1), (-1, 1, 0), (-1, 1, 1), (-1, 1, -1), (-1, -1, 0), (-1, -1, 1), (-1, -1, -1)]

Это возвращает:

[[(0, 0, 0),
  (0, 0, 1),
  (0, 1, 0),
  (0, 1, 1),
  (1, 0, 0),
  (1, 0, 1),
  (1, 1, 0),
  (1, 1, 1)],
 [(0, 0, 0),
  (0, 0, -1),
  (0, 1, 0),
  (0, 1, -1),
  (1, 0, 0),
  (1, 0, -1),
  (1, 1, 0),
  (1, 1, -1)],
 [(0, 0, 0),
  (0, 0, 1),
  (0, -1, 0),
  (0, -1, 1),
  (1, 0, 0),
  (1, 0, 1),
  (1, -1, 0),
  (1, -1, 1)],
 [(0, 0, 0),
  (0, 0, -1),
  (0, -1, 0),
  (0, -1, -1),
  (1, 0, 0),
  (1, 0, -1),
  (1, -1, 0),
  (1, -1, -1)],
 [(0, 0, 0),
  (0, 0, 1),
  (0, 1, 0),
  (0, 1, 1),
  (-1, 0, 0),
  (-1, 0, 1),
  (-1, 1, 0),
  (-1, 1, 1)],
 [(0, 0, 0),
  (0, 0, -1),
  (0, 1, 0),
  (0, 1, -1),
  (-1, 0, 0),
  (-1, 0, -1),
  (-1, 1, 0),
  (-1, 1, -1)],
 [(0, 0, 0),
  (0, 0, 1),
  (0, -1, 0),
  (0, -1, 1),
  (-1, 0, 0),
  (-1, 0, 1),
  (-1, -1, 0),
  (-1, -1, 1)],
 [(0, 0, 0),
  (0, 0, -1),
  (0, -1, 0),
  (0, -1, -1),
  (-1, 0, 0),
  (-1, 0, -1),
  (-1, -1, 0),
  (-1, -1, -1)]]
0 голосов
/ 23 февраля 2019

Составьте список списков.Индекс каждого большого списка - это двоичное направление сравнения: 1 или True для положительного, 0 или False для отрицательного.Назовите это mask.

Итерация всех возможных масок, от 0 до 2 ^ n-1.Для каждой маски преобразуйте логический вектор в последовательность коэффициентов.Например, маска 9 является двоичной 1001, последовательностью коэффициентов [1, -1, -1, 1].Умножьте кортеж на маску;например,

(0, 1, -1, 1) * [1, -1, -1, 1] => [0, -1, 1, 1]

Используйте функцию all для фильтрации всего вектора, учитывая mask и element из вашего списка кандидатов.

all(bit >= 0 for bit in 
    [element[i] * mask[i] for i in len(element)])

СейчасОберните это в цикле итерации по вашим значениям маски.Если вы достаточно настойчивы, вы можете создать весь список из 2 ^ n отфильтрованных списков в одной строке кода, используя all и вложенные понимания.Я предлагаю оставить это для ночного взлома, а не для решения проблем.

Также обратите внимание, что itertools.permutations будет рад сгенерировать маски для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...