Python - Сужение перестановок itertools приводит к операторам if. Как с повторным элементом?

Относительный новичок Python/ программирования здесь. Я играю с методом перестановок itertools, чтобы сузить полученные результаты с помощью оператора "if" для создания нужного мне списка.

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

from itertools import permutations

prp1 = ["UP", ",", "DOWN", "LEFT", ",", "RIGHT"]

# grab indices for commas in 'prp1' list
comma_indices = []
for index, p in enumerate(prp1):
    if p == ",":
        commas.append(index)

perms = permutations(prp1)
lst = []
for perm in perms:
    # Presently I have manually inserted the indices of commas,
    # but how to do this non-manual for unknown amount of commas here?
    if perm[1] == ',' and perm[4] == ',':
        lst.append(perm)

for l in lst:
    print l

Я думал о том, чтобы сделать что-то вроде этого:

for perm in perms:
    for comma in commas:
        if...........

..но тогда я получаю только 1 запятую за раз.

Любая помощь высоко ценится, Даррен

РЕДАКТИРОВАТЬ:

Еще несколько примеров списков, которые нужно будет переставить:

prp2 = ['down', ',', 'up', 'left', 'down']
prp3 = ['down', 'down', ',', 'up', ',', 'left', ',', 'right', ',', 'left']

1 ответ

Решение

Вы уже знаете, как найти индексы, где запятые расположены без жесткого кодирования:

comma_indices = []
for index, p in enumerate(prp1):
    if p == ",":
        commas.append(index)

Таким образом, вы можете применить тот же подход к perm и посмотреть, если это соответствует, например,

observed_comma_indices = [index for index, p in enumerate(perm) if p == ","]
if comma_indices == observed_comma_indices:
    lst.append(perm)

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

from itertools import permutations

def permute_some(seq, indices_to_permute):
    for perm in permutations(indices_to_permute):
        newseq = seq[:]
        for i, p in zip(indices_to_permute, perm):
            newseq[i] = seq[p]
        yield newseq

который дает

>>> seq = ["A", "B", ",", "C", ","]
>>> perm_ii = [i for i,x in enumerate(seq) if x != ","]
>>> for p in permute_some(seq, perm_ii):
...     print p
...     
['A', 'B', ',', 'C', ',']
['A', 'C', ',', 'B', ',']
['B', 'A', ',', 'C', ',']
['B', 'C', ',', 'A', ',']
['C', 'A', ',', 'B', ',']
['C', 'B', ',', 'A', ',']
Другие вопросы по тегам