Раздельное сочетание двух отдельных списков, сохраняющих соответствие / зависимость друг от друга - PullRequest
0 голосов
/ 20 марта 2019

У меня есть два списка одинаковой длины, которые имеют однозначное соответствие:

a = [1,2,3,4]
b = [6,7,8,9]

Я хочу найти комбинации этих двух списков отдельно.Но индексы комбинированных элементов должны быть одинаковыми для обоих списков.

Например, если я сделаю:

list(itertools.combinations(a,2))

Я могу получить

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

Я мог бы получить

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

тоже, потому чтооба одинаковы.

Поэтому, какую бы комбинацию я не получил, я хочу, чтобы одинаковые индексы были объединены и для второго списка.

Так что, если

list(itertools.combinations(a,2))

даст мне

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

, тогда

list(itertools.combinations(b,2))

должно дать мне

[(6,7),(6,8),(6,9),(8,7),(9,7),(9,8)]

или если

list(itertools.combinations(a,2))

дает мне

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

, тогда

list(itertools.combinations(b,2))

должно дать мне

[(7,6),(8,6),(9,6),(7,8),(7,9),(8,9)]

Ответы [ 5 ]

1 голос
/ 20 марта 2019

Вы можете генерировать комбинации по индексам, а затем индексировать a и b.Например:

a = [1,2,3,4]
b = [6,7,8,9]
for i0,i1 in itertools.combinations(range(len(a)), 2):
  print("{0},{1}  -->  {2},{3}".format(a[i0],a[i1],b[i0],b[i1]))


1,2  -->  6,7
1,3  -->  6,8
1,4  -->  6,9
2,3  -->  7,8
2,4  -->  7,9
3,4  -->  8,9
1 голос
/ 20 марта 2019

Из официальной документации Python itertools Документация :

"Комбинации генерируются в лексикографическом порядке сортировки. Таким образом, если итеративный ввод отсортирован, комбинации кортежей будут производиться в отсортированном порядке."

Таким образом, для отсортированного списка порядок всегда будет одинаковым, начиная с первого значения.

1 голос
/ 20 марта 2019

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

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

a = [4,3,2,1]

list(combinations(a,2))
[(4, 3), (4, 2), (4, 1), (3, 2), (3, 1), (2, 1)]

list(combinations(sorted(a),2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

https://docs.python.org/3/library/itertools.html#itertools.combinations

0 голосов
/ 20 марта 2019

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

a = [1,2,3,4]
b = [6,7,8,9]

from itertools import combinations

list( combinations(zip(a,b),2))

Это дает:

[((1, 6), (2, 7)),
 ((1, 6), (3, 8)),
 ((1, 6), (4, 9)),
 ((2, 7), (3, 8)),
 ((2, 7), (4, 9)),
 ((3, 8), (4, 9))]

Вы можете видеть, что они совпадаютпо спискам.

0 голосов
/ 20 марта 2019

Ключ здесь должен использовать itertools.permutations вместо itertools.combinations. Вот возможная реализация, которая сэкономит немного времени, вычисляя перестановки один раз:

import itertools

def isomorphic_permutations(*arrays, **kwargs):
    arrays_shape = len(arrays[0])
    if any(len(a) != arrays_shape for a in arrays):
        raise ValueError("All input arrays should have the same size.")
    permutations = list(itertools.permutations(range(arrays_shape), **kwargs))
    for array in arrays:
        yield ((array[x], array[y]) for x, y in permutations)

kwarg r используется для построения перестановки с itertools.permutations(iterable, r=None). Это соответствует длине перестановок. Вот как вы можете использовать эту функцию:

a = [7,6,8]
b = [6,7,8]
for permutation in isomorphic_permutations(a, b, r=2):
    print(list(permutation))

Который выдаст:

[(7, 6), (7, 8), (6, 7), (6, 8), (8, 7), (8, 6)]
[(6, 7), (6, 8), (7, 6), (7, 8), (8, 6), (8, 7)]

Обратите внимание, как инверсия 6 и 7 отражается на выходных перестановках.

...