Python, список пар элементов из других списков - PullRequest
2 голосов
/ 22 марта 2019

У меня есть серия списков, назовите их A, B, C, D, E. Теперь у каждого списка есть 5 элементов с одинаковыми именами, скажем:

A: [ 'Cars_A', 'Planes_A', 'Houses_A', 'Bikes_A' ] 
B: [ 'Cars_B', 'Planes_B', 'Houses_B', 'Bikes_B' ]
etc..

Мне нужен список списков в форме:

[ ['Cars_A', 'Planes_B'], ['Cars_A', 'Houses_B'], ['Cars_A', 'Bikes_B'], 
  ['Planes_A', 'Cars_B'], ['Planes_A', 'Houses_B'], ['Planes_A', 'Bikes_B'],
  ['Houses_A', 'Cars_B'], ['Houses_A', 'Planes_B'], ['Houses_A', 'Bikes_B'],
  ['Bikes_A', 'Cars_B'], ['Bikes_A', 'Planes_B'], ['Bikes_A', 'Houses_B'] ] 

Как видно, правило для этого списка:

  • Элемент не может быть сгруппирован с другим элементом из того же набора, например, ['Cars_A', 'Planes_A'] не допускается.
  • Элемент не может быть сгруппирован с аналогичным элементом из другого набора, например ['Cars_A', 'Cars_B'] не допускается.

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

Ответы [ 3 ]

2 голосов
/ 22 марта 2019

Использование itertools.permutations и itertools.product с filter:

import itertools

l = [['_'.join([i,g])for i in ['cars', 'planes', 'houses', 'bikes']] for g in 'ABCDE']
l    
[['cars_A', 'planes_A', 'houses_A', 'bikes_A'],
 ['cars_B', 'planes_B', 'houses_B', 'bikes_B'],
 ['cars_C', 'planes_C', 'houses_C', 'bikes_C'],
 ['cars_D', 'planes_D', 'houses_D', 'bikes_D'],
 ['cars_E', 'planes_E', 'houses_E', 'bikes_E']]

res = []
for sub in itertools.permutations(l, 2):
    res.extend(list(filter(lambda x: (x[0].split('_')[0]!=x[1].split('_')[0]), itertools.product(*sub))))    
res
[('cars_A', 'planes_B'),
 ('cars_A', 'houses_B'),
 ('cars_A', 'bikes_B'),
 ('planes_A', 'cars_B'),
 ('planes_A', 'houses_B'),
 ('planes_A', 'bikes_B'),
 ('houses_A', 'cars_B'),
 ...
 ('bikes_E', 'cars_D'),
 ('bikes_E', 'planes_D'),
 ('bikes_E', 'houses_D')]
0 голосов
/ 22 марта 2019

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

from collections import deque
A=[ 'Cars_A', 'Planes_A', 'Houses_A', 'Bikes_A' ] 
B=[ 'Cars_B', 'Planes_B', 'Houses_B', 'Bikes_B' ]

l=[deque(A),deque(B)]
n = 0
for i in l:
    i.rotate(n)
    n += 1
m = zip(*l)
print(list(m))
0 голосов
/ 22 марта 2019

Вот простой способ использования itertools.combinations, давайте сначала создадим все пары, а затем filter.

from itertools import combinations

def filter_(tup):
    x, y = tup
    p1 = x.split('_')
    p2 = y.split('_')
    return (p1[0] != p2[0]) and (p1[1] != p2[1])


list(filter(filter_, combinations([*A, *B], 2)))

[('Cars_A', 'Planes_B'),
 ('Cars_A', 'Houses_B'),
 ('Cars_A', 'Bikes_B'),
 ('Planes_A', 'Cars_B'),
 ('Planes_A', 'Houses_B'),
 ('Planes_A', 'Bikes_B'),
 ('Houses_A', 'Cars_B'),
 ('Houses_A', 'Planes_B'),
 ('Houses_A', 'Bikes_B'),
 ('Bikes_A', 'Cars_B'),
 ('Bikes_A', 'Planes_B'),
 ('Bikes_A', 'Houses_B')]


list(filter(filter_, combinations([*A, *B, *C], 2)))

[('Cars_A', 'Planes_B'),
 ('Cars_A', 'Houses_B'),
 ('Cars_A', 'Bikes_B'),
 ('Cars_A', 'Planes_C'),
 ('Cars_A', 'Houses_C'),
 ('Cars_A', 'Bikes_C'),
 ('Planes_A', 'Cars_B'),
 ('Planes_A', 'Houses_B'),
 ('Planes_A', 'Bikes_B'),
 ('Planes_A', 'Cars_C'),
 ('Planes_A', 'Houses_C'),
 ('Planes_A', 'Bikes_C'),
 ('Houses_A', 'Cars_B'),
  ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...