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

Я пытаюсь получить список списков (или кортежей), который следует шаблону примерно так:

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

Используя itertools.combinations_with_replacement, я подошел близко, но в итоге получаются списки, которые содержат значения перехода, например:

[1,1,1,3]
or
[2,2,2,3]

Я не хочу этого. Я всегда хочу начинать с 1 и увеличивать до заполнения списка, а затем увеличивать до следующего значения.

Если я использую itertools, есть ли способ удалить списки, которые мне не нужны?


person Canada    schedule 04.02.2021    source источник
comment
Итак, вы хотите, чтобы все они начинались с 1 и никогда не увеличивались более чем на 1?   -  person schwobaseggl    schedule 04.02.2021
comment
Можете ли вы объяснить, точно, что здесь за закономерность? Почему он не начинается с [1, 1, 1, 1]? Почему вы поднимаетесь на [1, 2, 2, 2], а не на [2, 2, 2, 2]? Что не так с [2, 2, 2, 3]? Что будет после [1, 2, 3, 4]? Должен быть [1, 1, 2, 3]? Каким должен быть полный выход?   -  person tzaman    schedule 04.02.2021
comment
@tzaman, это на самом деле для объединения некоторых данных для машинного обучения. На самом деле это вопрос, аналогичный этому: stackoverflow.com/questions/66050937/   -  person Canada    schedule 04.02.2021
comment
@schwobaseggl да! И теперь у меня есть два решения, так что все равно спасибо! :)   -  person Canada    schedule 04.02.2021


Ответы (2)


Вместо использования комбинаций я бы сгенерировал паттерн напрямую.

Создайте список из единиц желаемой длины и повторяйте в обратном направлении, соответствующим образом изменяя список.

def generate_increment(n):
    lst = [1] * n
    result = []
    for k in range(n-1):
        lst[-1] += 1
        result.append(lst[:])
        for i in range(len(lst)-2, k, -1):
            a, b = lst[i], lst[i+1]
            if a != b:
                lst[i] = b
                result.append(lst[:])
    return result

>>print(*generate_increment(4), sep='\n')

[1, 1, 1, 2]
[1, 1, 2, 2]
[1, 2, 2, 2]
[1, 2, 2, 3]
[1, 2, 3, 3]
[1, 2, 3, 4]
person bncpr    schedule 04.02.2021
comment
Спасибо, это именно то, что я искал! - person Canada; 04.02.2021

Кажется, что проверка результатов combinations потребует больших усилий, чем просто создание тех списков, которые вам нужны.

Это можно сделать с помощью рекурсивной функции, которая на каждом шаге добавляет, какое значение добавить в список до определенного размера:

def gen_list(pre, size):
    if size == 1:
        return [pre]

    res = gen_list(pre + [pre[-1]], size - 1)
    res.extend(gen_list(pre + [pre[-1]+1], size-1))
    return res

for l in gen_list([1], 4):
    print(l)

Какие отпечатки:

[1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 2, 2]
[1, 1, 2, 3]
[1, 2, 2, 2]
[1, 2, 2, 3]
[1, 2, 3, 3]
[1, 2, 3, 4]
person Tomerikoo    schedule 04.02.2021
comment
Спасибо, это именно то, что я искал! - person Canada; 04.02.2021