2011-09-11 13 views

Respuesta

22

parece que quiere itertools.combinations:

>>> list(itertools.combinations((1, 2, 3), 2)) 
[(1, 2), (1, 3), (2, 3)] 

Si desea conjuntos que tendrá que convertir explícitamente.

>>> s = set((1, 2, 3)) 
>>> map(set, itertools.combinations(s, 2)) 
[set([1, 2]), set([1, 3]), set([2, 3])] 
+0

¡Maldición !, por cierto su mapa se puede hacer con una lista comp '[set (i) for i in itertools.combinations (s, 2))] ' –

1

Este es un subconjunto de la power set de {1, 2, 3} (o cualquier conjunto) que contiene todos los conjuntos de dos elementos.

Consulte el Python itertools documentation y busque el término "powerset" para obtener una respuesta general a este problema.

1

sólo para dar otro punto de vista, me puse a buscar una manera de recorrer todo el subconjunto de tamaño 2 de {1.....N}, por lo que poner itertools.combinations en la prueba:

import itertools 
from time import time 


N = 7000 
lst = [i for i in xrange(N)] 

st = time() 
c1 = 0 
for x in itertools.combinations(lst, 2): 
    c1 += 1 
print "combinations: %f" % (time()-st) 

st = time() 
c2=0 
for x in xrange(N): 
    for y in xrange(x): 
     c2 += 1 
print "double loop: %f" % (time()-st) 
print "c1=%d,c2=%d" % (c1,c2) 

# prints: 
#combinations: 4.247000 
#double loop: 3.479000 
# c1=24496500,c2=24496500 

así que supongo que no siempre se debe convertir en general solución ... Si sabe de antemano el tamaño del subconjunto que desea, debería ser más eficiente iterar usando ciclos for.

También tenga en cuenta que no debe iterar sobre list(itertools.combinations(lst, 2)) ya que este movimiento crea la lista (y mucho más lento que usar el generador).

+1

Estas dos pruebas no hacen lo mismo cosa. 'itertools.combinations' en realidad crea una tupla; su ciclo anidado no crea una tupla. – senderle

+1

Hice una prueba rápida. Si realmente necesita crear tuplas dentro del bucle anidado, es más lento en un 50%. Además, si no necesita utilizar un bucle 'for' para procesar la salida de' itertools.combinations', puede obtener una aceleración sustancial con esta expresión de generador: 'c3 = sum (1 para el par en itertools.combinations (lst, 2)) '. Eso corre alrededor de 40% más rápido que el bucle anidado más rápido. ¡Siempre hay muchas sutilezas a considerar al optimizar este tipo de código! – senderle

Cuestiones relacionadas