2011-11-23 39 views
5

No encontré una mejor manera de expresar esta pregunta en el título. Si puedes, edita.cómo obtener todas las combinaciones posibles de elementos de la lista bidimensional en python?

Tengo una lista de las listas de la siguiente manera:

a = [['a','b'],[1,2]] 

ahora, me gustaría una función que escupe toda combinación posible de esta manera:

[['a',1],['a',2],['b',1],['b',2]] 

donde ni el número de listas en a se conoce de antemano, y la longitud de cada sublista no se conoce con antelación, pero todas las combinaciones que salen deben contener 1 elemento de cada sublista.

Respuesta

11

Es necesario itertools.product():

>>> list(itertools.product(*a)) 
[('a', 1), ('a', 2), ('b', 1), ('b', 2)] 
+0

Para cualquier persona que se pregunta, el * frente a un desempaqueta la lista: http://stackoverflow.com/a/2921893/4549682 – wordsforthewise

0

Esto puede ser lo itertools.product() (que menciona Sven) hace:

def combs(list1, list2): 
    results = [] 
    for x in list1: 
     for y in list2: 
      l.append([x,y]) 
    return results 
+0

que funcionaría si siempre sólo tenía 2 sublistas, como en el ejemplo '[[1,2], ['a', 'b']], y luego pasaría las dos listas secundarias a esta función, pero este no es el caso, la lista podría ser' [[ 'a', 'b', 'c'], [1,2], [{}, [],()]] ', así que ahora tenemos 3 sublistas, entonces lo que necesitaríamos es una función donde multiplicar un número variable de listas. – bigblind

+0

Ah, supuse por su ejemplo que siempre serían pares. No tengo una mejor sugerencia entonces. – Anko

0

Aquí es una solución utilizando la recursividad, combs_r tiene accum digerir head (la siguiente lista en línea) para producir un gordo accum0, y luego se llama a sí mismo ("recursividad") con tail (las listas restantes) y el ahora más gordo acumula accum0.

Puede ser un gran usuario de la memoria ya que cada llamada a combs_r agrega un nuevo espacio de nombres, hasta el final cuando todo se desenrolla. Una persona más perceptible en Python interna podría comentar sobre esto.

Paga para aprender prólogo, en mi humilde opinión.

def combs(ll): 
    if len(ll) == 0: 
     return [] 
    if len(ll) == 1: 
     return [[item] for item in ll[0]] 
    elif len(ll) == 2: 
     return lmul(ll[0], [[item] for item in ll[1]]) 
    else: 
     return combs_r(ll[1:], ll[0]) 

def combs_r(ll, accum): 
    head = ll[0] 
    tail = ll[1:] 
    accum0 = [] 
    accum0 = lmul(head, accum) 
    if len(tail) == 0: 
     return accum0 
    else: 
     return combs_r(tail, accum0) 

def lmul(head, accum): 
    accum0 = [] 
    for ah in head: 
     for cc in accum: 
      #cc will be reused for each ah, so make a clone to mutate 
      cc0 = [x for x in cc] 
      cc0.append(ah) 
      accum0.append(cc0) 
    return accum0 

sampleip = [['a','b','c'],[1,2], ['A', 'B']] 
sampleip2 = [['a','b','c'],[1,2]] 
sampleip1 = [['a','b','c']] 
sampleip0 = [] 
print combs(sampleip0) 
print combs(sampleip1) 
print combs(sampleip2) 
print combs(sampleip) 
Cuestiones relacionadas