Удаление похожих элементов из вложенного списка - PullRequest
1 голос
/ 11 февраля 2020

Я создаю вложенный список, используя следующий код:

from itertools import combinations


def get_nested_list(arr, n, k):
    iterator = 0
    nest = []

    for i in range(1, n):

        for combo in combinations(arr, i):
            odd_num = 0

            for item in combo:
                if item % 2 != 0:
                    odd_num += 1

            if odd_num <= k:
                iterator += 1
                nest.append(combo)

    nest = [list(i) for i in nest]
    return nest


a = [1, 2, 3, 4]
b = len(a)
c = 1

print(get_nested_list(a, b, c))

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

[[1], [2], [3], [4], [1, 2], [1, 4], [2, 3], [2, 4], [3, 4], [1, 2, 4], [2, 3, 4]]

Однако я получил такие элементы, как [1,2] и [1,4] которые имеют одинаковое значение х, [2, 4] и [3, 4], которые имеют одинаковое значение у. Как я могу создать список с совершенно разными подсписками? Вот что я пытаюсь сделать sh:

[[1], [2], [3], [4], [1, 2], [2, 3], [3, 4], [2, 3, 4]]

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

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

def overlapping_chunks(size, sequence):
    """Yield overlapping chunks of sequence."""
    for i in range(len(sequence)-size+1):
        yield sequence[i:i+size]

def powerchunk(sequence):
    """Yield all overlapping chunks of sequence, similar to a powerset."""
    for size in range(1, len(sequence)+1):
        yield from overlapping_chunks(size, sequence)

a = [1, 2, 3, 4]
max_odds = 1
result = [
    chunk for chunk in powerchunk(a)
    if sum(item % 2 != 0 for item in chunk) <= max_odds
    ]
print(result)  # -> [[1], [2], [3], [4], [1, 2], [2, 3], [3, 4], [2, 3, 4]]

Похожие: Разделение списка Python на список перекрывающихся кусков

0 голосов
/ 11 февраля 2020

Выбранный ответ, очевидно, проще, но я работал над этим, поэтому в любом случае отправляю свой ответ. Он использует defaultdict и некоторые логики c, чтобы проверить, была ли там существующая запись с тем же индексом и такой же длины.

from itertools import combinations
from collections import defaultdict

def get_nested_list(arr, n, k):
    iterator = 0
    nest = []
    d = defaultdict(set)

    for i in range(1, n):

        for combo in combinations(arr, i):
            odd_num = 0

            for item in combo:
                if item % 2 != 0:
                    odd_num += 1

            if odd_num <= k:
                iterator += 1
                skip = False
                len_c = len(combo)
                for j, n in enumerate(combo):
                    if n in d.get((len_c, j), set()):
                        skip = True
                        break
                    d[(len_c, j)].add(n)
                if skip: continue
                nest.append(combo)

    nest = [list(i) for i in nest]
    return nest

a = [1, 2, 3, 4]
b = len(a)
c = 1
res = get_nested_list(a, b, c)
print(res)

assert res == [[1], [2], [3], [4], [1, 2], [2, 3], [3, 4], [1, 2, 4]]
...