2016-10-05 3 views
0

У меня есть эта форма спискаiItertools.product с переменной валидации

data = [ 
    [ 
    {'name': 's11', 'class': 'c1'}, {'name': 's12', 'class': 'c2'} 
    ], 
    [ 
    {'name': 's21', 'class': 'c2'}, {'name': 's22', 'class': 'c2'} 
    ], 
    [ 
    {'name': 's31', 'class': 'c1'}, {'name': 's32', 'class': 'c1'} 
    ] 
] 

с помощью itertools.product(data) я получаю все возможные комбинации, необходимые, принимая один элемент из каждого списка в основных данных списка. Что я хочу сделать, я хочу пропустить, если элемент в первом подсписке имеет другой класс во втором или третьем подсписке.

Does itertools.product предоставляет любые варианты проверки для такого случая?

Ожидаемые результаты должны быть:

({'name': 's11', 'class': 'c1'},{'name': 's31', 'class': 'c1'}), 
({'name': 's11', 'class': 'c1'}, {'name': 's32', 'class': 'c1'}), 
({'name': 's12', 'class': 'c2'},{'name': 's21', 'class': 'c2'}), 
({'name': 's12', 'class': 'c2'},{'name': 's22', 'class': 'c2'}), 
+1

Нет, это не так. –

+0

@ juanpa.arrivillaga есть ли какой-либо другой способ сделать это – f0unix

+1

@ f0unix, пожалуйста, добавьте к вопросу результат, который вы хотите получить. – skovorodkin

ответ

1
from itertools import chain, combinations, product 
result = [ 
    (a, b) for a, b 
    in chain.from_iterable(product(*l) for l in combinations(data, 2)) 
    if a['class'] == b['class'] 
] 
+0

Итак, этот ответ действительно близок к моему другому сообщению [здесь] (http://stackoverflow.com/a/39835618/847552), вам просто нужно отфильтровать нежелательные элементы. – skovorodkin

0

Почти такой же, как @skovorodkin отвечал.

from itertools import product, chain 

data = [ 
    [{'name': 's11', 'class': 'c1'}, {'name': 's12', 'class': 'c2'}], 
    [{'name': 's21', 'class': 'c2'}, {'name': 's22', 'class': 'c2'}], 
    [{'name': 's31', 'class': 'c1'}, {'name': 's32', 'class': 'c1'}] 
] 
output = [i for i in product(data[0], chain.from_iterable(data[1:])) if i[0]['class'] == i[1]['class']] 
output 

Выход:

[({'class': 'c1', 'name': 's11'}, {'class': 'c1', 'name': 's31'}), 
({'class': 'c1', 'name': 's11'}, {'class': 'c1', 'name': 's32'}), 
({'class': 'c2', 'name': 's12'}, {'class': 'c2', 'name': 's21'}), 
({'class': 'c2', 'name': 's12'}, {'class': 'c2', 'name': 's22'})] 

UPDATE

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

@skovorodkin ответ:

>>> %timeit result = [(a, b) for a, b in chain.from_iterable(product(*l) for l in combinations(data, 2)) if a['class'] == b['class']] 
The slowest run took 8.56 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 3.69 µs per loop 

Мой ответ:

>>> %timeit output = [i for i in product(data[0], chain.from_iterable(data[1:])) if i[0]['class'] == i[1]['class']] 
The slowest run took 10.37 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 2.43 µs per loop