Сочетание уникальных продуктов с itertools - PullRequest
0 голосов
/ 20 ноября 2018

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

test = [[('juice', 'NOUN'), ('orange', 'FLAVOR')], 
        [('juice', 'NOUN'), ('orange', 'FLAVOR'), ('lemon', 'FLAVOR')],
        [('orange', 'FLAVOR'), ('chip', 'NOUN')]]

То, что я ожидаю, выглядит примерно так:

[(('juice', 'NOUN'), ('lemon', 'FLAVOR')), 
 (('juice', 'NOUN'), ('chip', 'NOUN')),
 (('orange', 'FLAVOR'), ('lemon', 'FLAVOR')),
 (('orange', 'FLAVOR'), ('chip', 'NOUN')),
 (('lemon', 'FLAVOR'), ('chip', 'NOUN'))]

То естьЯ хотел бы получить перестановку по спискам, но только для уникальных предметов.Я предпочитаю использовать itertools.Раньше я пытался list(itertools.product(*test)) Но я понял, что получится произведение длины вложенного списка ...

Мой текущий код:

unique_list = list(set(itertools.chain(*test)))
list(itertools.combinations(unique_list, 2))

Мой мыслительный процесс состоит в том, чтобы получитьсначала уникальные элементы во вложенном списке, поэтому вложенный список будет [[('juice', 'NOUN'), ('orange', 'FLAVOR')], [('lemon', 'FLAVOR')], [('chip', 'NOUN')]], а затем используйте itertools.combinations для перестановки.Тем не менее, он будет переставлять в списке (т.е. сок и апельсин появляются вместе), что я не хочу в моих результатах.

1 Ответ

0 голосов
/ 20 ноября 2018

Это делает то, что вы хотите без , фиксируя размер исходного списка на 3:

Ввод:

test = [[('juice', 'NOUN'), ('orange', 'FLAVOR')], 
        [('juice', 'NOUN'), ('orange', 'FLAVOR'), ('lemon', 'FLAVOR')],
        [('juice', 'NOUN'), ('chip', 'NOUN')]]

Сначала переформатируйте ввод, чтобы удалить дубликаты (см. примечание 1):

test = [[x for x in sublist if x not in sum(test[:i], [])] for i, sublist in enumerate(test)]

Наконец, получите произведение из комбинаций .

from itertools import combinations, product

for c in combinations(test, 2):
    for x in product(*c):
        print(x)

, которое производит:

(('juice', 'NOUN'), ('lemon', 'FLAVOR'))
(('orange', 'FLAVOR'), ('lemon', 'FLAVOR'))
(('juice', 'NOUN'), ('chip', 'NOUN'))
(('orange', 'FLAVOR'), ('chip', 'NOUN'))
(('lemon', 'FLAVOR'), ('chip', 'NOUN'))

  1. удаляет внутренние кортежи, если они были замечены в любом из предыдущих подсписков.Волшебство здесь делается с помощью sum(test[:i], []), который «добавляет» все предыдущие подсписки вместе, чтобы выполнить только одну проверку членства.

Существует также версия списка для понимания списка длякомпактность и стильность:

res = [x for c in combinations(test, 2) for x in product(*c)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...