Почему itertools.combinations добавляет дополнительные запятые в вывод и как этого избежать?

#python #combinations #itertools

Вопрос:

Я хочу иметь все возможные комбинации длиной до 2 пунктов в моем списке. Я хочу, чтобы это было однострочно, я знаю, как сделать это в большем количестве строк. Когда я попробую это:

 mylist=[1, 2, 3, 4]
[x for l in range(1,3) for x in itertools.combinations(mylist, l)]
 

Я получаю этот результат с запятыми, добавленными к комбинациям длины 1.

 [(1,), (2,), (3,), (4,), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
 

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

 [(1), (2), (3), (4), (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
 

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

1. (1,) укажите, что они являются кортежем

2. Конечно, я мог бы просто удалить их — как именно?

Ответ №1:

Это потому, что если нет запятой, кортежи с одним значением не могут быть кортежами:

 >>> (1,)
(1,)
>>> (1)
1
>>> 
 

Так что то, чего ты хочешь, невозможно.

Но вы можете преобразовать кортежи одиночных значений в целые числа, как это:

 print([x if len(x) > 1 else x[0] for l in range(1,3) for x in itertools.combinations(mylist, l)])
 

Выход:

 [1, 2, 3, 4, (1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
 

Ответ №2:

Вы хотите только использовать tuple ? это из-за одного элемента в tuple , разве не нормально использовать list ? как показано ниже:

 mylist=[1, 2, 3, 4]
[list(x) for l in range(1,3) for x in itertools.combinations(mylist, l)]
 

выход:

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

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

1. Да, я бы на самом деле предпочел иметь их в виде списков, теперь, когда вы упомянули об этом. Спасибо!

Ответ №3:

 itertools.combinations
 

возвращает кортеж.
Цитата из документов:

Возвращает подпоследовательности длины r элементов из входных итераций. Если вы заметили эквивалентный код, вы можете увидеть, что

 yield tuple(pool[i] for i in indices)
 

Это порождающий кортеж.

И если в кортеже есть один элемент, должна быть запятая, чтобы сказать python, что это кортеж. Например:

 >>> ('a')
'a'
>>> ('a',)
('a',)
 

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

 [list(x) for l in range(1,3) for x in itertools.combinations(mylist, l)]