itertools.product eliminando elementos repetidos.

¿Cómo puedo omitir las tuplas que tienen elementos duplicados en la iteración cuando uso itertools.product ? O digamos, ¿hay alguna manera de no mirarlos en la iteración? Porque saltarse puede llevar mucho tiempo si el número de listas es demasiado alto.

Example, lis1 = [1,2] lis2 = [2,4] lis3 = [5,6] [i for i in product(lis1,lis2,lis3)] should be [(1,2,5), (1,2,6), (1,4,5), (1,4,6), (2,4,5), (2,4,6)] 

No tendrá (2,2,5) y (2,2,6) ya que 2 está duplicado aquí. ¿Cómo puedo hacer eso?

itertools generalmente trabaja en posiciones únicas dentro de entradas, no en valores únicos. Por lo tanto, cuando desea eliminar valores duplicados, generalmente tiene que postprocesar la secuencia de resultados de itertools o “rodar los suyos”. Debido a que el procesamiento posterior puede ser muy ineficiente en este caso, haga su propio rollo:

 def uprod(*seqs): def inner(i): if i == n: yield tuple(result) return for elt in sets[i] - seen: seen.add(elt) result[i] = elt for t in inner(i+1): yield t seen.remove(elt) sets = [set(seq) for seq in seqs] n = len(sets) seen = set() result = [None] * n for t in inner(0): yield t 

Entonces, por ejemplo,

 >>> print list(uprod([1, 2, 1], [2, 4, 4], [5, 6, 5])) [(1, 2, 5), (1, 2, 6), (1, 4, 5), (1, 4, 6), (2, 4, 5), (2, 4, 6)] >>> print list(uprod([1], [1, 2], [1, 2, 4], [1, 5, 6])) [(1, 2, 4, 5), (1, 2, 4, 6)] >>> print list(uprod([1], [1, 2, 4], [1, 5, 6], [1])) [] >>> print list(uprod([1, 2], [3, 4])) [(1, 3), (1, 4), (2, 3), (2, 4)] 

Esto puede ser mucho más eficiente, ya que un valor duplicado ni siquiera se considera (ni dentro de una entrada iterable, ni a través de ellos).

 lis1 = [1,2] lis2 = [2,4] lis3 = [5,6] from itertools import product print [i for i in product(lis1,lis2,lis3) if len(set(i)) == 3] 

Salida

 [(1, 2, 5), (1, 2, 6), (1, 4, 5), (1, 4, 6), (2, 4, 5), (2, 4, 6)] 

Con itertools.combinations no habrá elementos repetidos en orden ordenado:

 >>> lis = [1, 2, 4, 5, 6] >>> list(itertools.combinations(lis, 3)) [(1, 2, 4), (1, 2, 5), (1, 2, 6), (1, 4, 5), (1, 4, 6), (1, 5, 6), (2, 4, 5), (2, 4, 6), (2, 5, 6), (4, 5, 6)]