[pyar] productos elementos de una lista

186 views
Skip to first unread message

Nehuen Diez

unread,
May 10, 2011, 12:28:16 PM5/10/11
to Python Argentina
Buenas.


Mi problema es el siguiente:

Tengo una lista con numeros, y quiero extraer de esa lista todos los productos posibles entre ellos, sin repetir y sin soplar (y ademas obtener los numeros mismos) :P

por ejemplo: l1 = [2, 3, 3]

quiero obtener: l2= [2, 3, 6, 9, 18]

 
Alguna idea?


Saludos Cordiales.
                            -Nehuen Diez-

Hugo Arregui

unread,
May 10, 2011, 12:34:06 PM5/10/11
to Python Argentina
Parece que estas buscando algo similar al producto cartesiano (consigo mismo),

fijate product en:
http://docs.python.org/library/itertools.html
_______________________________________________
pyar mailing list py...@python.org.ar
http://listas.python.org.ar/listinfo/pyar

PyAr - Python Argentina - Sitio web: http://www.python.org.ar/

Daniel Moisset

unread,
May 10, 2011, 12:50:25 PM5/10/11
to Python Argentina
On Tue, May 10, 2011 at 1:34 PM, Hugo Arregui <hugo.a...@gmail.com> wrote:
> Parece que estas buscando algo similar al producto cartesiano (consigo mismo),

producto cartesiano arma solamente pares, y arma tuplas en vez de multiplicar

Yo lo que haria es

import itertools, operator
def product(t): return reduce(operator.mul, t, 1)
l_con_unos = [1]*(len(l)-1) + l
productos = set(product(t) for t in itertools.combinations(l_con_unos, len(l)))

Eso te da un set

Saludos,
D.

Facundo Batista

unread,
May 10, 2011, 12:53:08 PM5/10/11
to Python Argentina
2011/5/10 Nehuen Diez <nehue...@gmail.com>:

> Tengo una lista con numeros, y quiero extraer de esa lista todos los
> productos posibles entre ellos, sin repetir y sin soplar (y ademas obtener
> los numeros mismos) :P
>
> por ejemplo: l1 = [2, 3, 3]
>
> quiero obtener: l2= [2, 3, 6, 9, 18]

>>> import operator, itertools
>>> todos = set()
>>> origen = [2, 3, 3]
>>> for i in range(1, len(origen) + 1):
... todos.update(reduce(operator.mul, x) for x in
itertools.combinations(origen, i))
...
>>> todos
set([9, 2, 3, 18, 6])
>>> sorted(todos)


[2, 3, 6, 9, 18]

--
.    Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/

"Matías A. Bellone"

unread,
May 10, 2011, 1:11:51 PM5/10/11
to Python Argentina
On 05/10/2011 01:28 PM, Nehuen Diez wrote:
> Buenas.
>
>
> Mi problema es el siguiente:
>
> Tengo una lista con numeros, y quiero extraer de esa lista todos los
> productos posibles entre ellos, sin repetir y sin soplar (y ademas
> obtener los numeros mismos) :P
>
> por ejemplo: l1 = [2, 3, 3]
>
> quiero obtener: l2= [2, 3, 6, 9, 18]
>

Probablemente haya una forma más fácil o más corta o más pythónica de
hacer esto (los dos loops anidados estoy casi seguro que se pueden
evitar) pero esta es la solución a la que llegué.

# itertools es una masa
from itertools import combinations
from operator import mul

def productos(lista):
ret = set() # el set remueve duplicados automáticamente
for x in xrange(len(lista)):
for comb in combinations(lista, x + 1): # de 1 a len
ret.add(reduce(mul, comb))
return sorted(list(ret))


Saludos,
Toote

Claudio Freire

unread,
May 10, 2011, 1:40:29 PM5/10/11
to Python Argentina
On Tue, May 10, 2011 at 6:50 PM, Daniel Moisset <dmoi...@machinalis.com> wrote:
> import itertools, operator
> def product(t): return reduce(operator.mul, t, 1)
> l_con_unos = [1]*(len(l)-1) + l
> productos = set(product(t) for t in itertools.combinations(l_con_unos, len(l)))

Algo más declarativoÑ

product = lambda t : reduce(operator.mul, t, 1)
productos = sorted(reduce(operator.or_,
(set(product(t) for t in itertools.combinations(l, n))
for n in xrange(1,len(l)+1))))

Y creo que más performante también. Creo.

Nehuen Diez

unread,
May 10, 2011, 10:57:33 PM5/10/11
to Python Argentina
Muy bueno gente ! Muchisisimas gracias. Exactamente lo que necesitaba :)


Saludos Cordiales.
                            -Nehuen Diez-


2011/5/10 Claudio Freire <klauss...@gmail.com>

p8queen

unread,
May 12, 2011, 12:13:41 AM5/12/11
to Python Argentina
una idea que nadie tiró:
Vos necesitas el conjunto de partes, o conjunto potencia o power set.
sea lista = [2,3,6]
el #(cardinal) del conjunto potencia de lista es 2**3 = 8.
Aqui hay algo curioso, con numeros binarios de 0 a 7
000
001
...
111

ej:sea binNum = '101' => multiplicamos 2*6.
listo, está a la vista la solucion.
hacés un bucle y la lista de numeros a multiplicar por cada vuelta del
bucle es la siguiente

[y for x,y in zip(binNum,lista) if a=='1']

python transforma a binario, pensalo.


--
Gustavo C

p8queen

unread,
May 12, 2011, 12:15:12 AM5/12/11
to Python Argentina
2011/5/12 p8queen <p8q...@gmail.com>:

> una idea que nadie tiró:
> Vos necesitas el conjunto de partes, o conjunto potencia o power set.
> sea lista = [2,3,6]
> el #(cardinal) del conjunto potencia de lista es 2**3 = 8.
> Aqui hay algo curioso, con numeros binarios de 0 a 7
> 000
> 001
> ...
> 111
>
> ej:sea binNum = '101' => multiplicamos 2*6.
> listo, está a la vista la solucion.
> hacés un bucle y la lista de numeros a multiplicar por cada vuelta del
> bucle es la siguiente
>
> [y for x,y in zip(binNum,lista) if a=='1']

me corrijo
[y for x,y in zip(binNum,lista) if x=='1']

Daniel Moisset

unread,
May 12, 2011, 8:59:56 AM5/12/11
to Python Argentina
2011/5/12 p8queen <p8q...@gmail.com>

>
> me corrijo
> [y for x,y in zip(binNum,lista) if x=='1']
>
> >
> > python transforma a binario, pensalo.

Me gusta pensarlo como powereset, pero usando la receta de
http://docs.python.org/library/itertools.html

def product(t):
return reduce(operator.mul, t, 1)

def powerset(iterable):
s = list(iterable)
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

l=[2,3,3]
print set(product(subset) for subset in powerset(l))


D.

Reply all
Reply to author
Forward
0 new messages