Получить все уникальные комбинации элементов из списка в Python - PullRequest
0 голосов
/ 15 января 2020

Я просмотрел много связанных вопросов, но никто не ответил мне, как получить ВСЕ комбинации элементов в списке. Например, с этим списком ввода

input_list = ["apple", "orange", "carrot"]

Я хотел бы иметь этот список:

output_list = [ ["apple"], ["orange"], ["carrot"], ["apple", "orange"],  ["apple", "carrot"], ["orange", "carrot"], ["apple", "orange", "carrot"]]

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

Ответы [ 4 ]

2 голосов
/ 15 января 2020

Вы ищете рецепт powerset itertools :

from itertools import chain, combinations

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

>>> input_list = ["apple", "orange", "carrot"]
>>> print(list(map(list, powerset(input_list)))[1:])
[['apple'], ['orange'], ['carrot'],['apple', 'orange'], ['apple', 'carrot'], ['orange', 'carrot'], ['apple', 'orange', 'carrot']]
1 голос
/ 15 января 2020

Ответ oneliner:

[list(j) for i in range(len(input_list )) for j in itertools.combinations(input_list , i+1)]

первый l oop (i) проходит через все различные комбинации и создает объект комбинации, затем второй l oop (j ) просматривает каждый элемент комбинации и составляет его список, а затем добавляет его в исходный список. Вывод получается так, как вы хотите, ничего не меняя.

1 голос
/ 15 января 2020

Документация itertools содержит набор полезных рецептов для вещей, легко реализуемых с помощью модуля; среди них генератор powerset:

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

Учитывая ваш список строк, вы получите список кортежей .

>>> list(powerset(input_list))
[(), ('apple',), ('orange',), ('carrot',), ('apple', 'orange'), ('apple', 'carrot'), ('orange', 'carrot'), ('apple', 'orange', 'carrot')]

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

>>> list(list(x) for x in powerset(input_list) if x != ())
[['apple'], ['orange'], ['carrot'], ['apple', 'orange'], ['apple', 'carrot'], ['orange', 'carrot'], ['apple', 'orange', 'carrot']]
1 голос
/ 15 января 2020

Это почти то, что вы ищете, за исключением некоторого форматирования:

from itertools import combinations
input_list = ["apple", "orange", "carrot"]
combis = [[i for i in combinations(input_list, 1)], [i for i in combinations(input_list, 2)], [i for i in combinations(input_list, 3)]]

Вывод:

 [[('apple',), ('orange',), ('carrot',)],
 [('apple', 'orange'), ('apple', 'carrot'), ('orange', 'carrot')],
 [('apple', 'orange', 'carrot')]]
...