tutorial for español else compressed comprehension python list-comprehension

for - python list comprehension tutorial



Python(Comprensión de la lista): devolver dos(o más) elementos para cada artículo (4)

Comprensión de la lista doble:

[f(x) for x in range(5) for f in (f1,f2)]

Manifestación:

>>> f1 = lambda x: x >>> f2 = lambda x: 10*x >>> [f(x) for x in range(5) for f in (f1,f2)] [0, 0, 1, 10, 2, 20, 3, 30, 4, 40]

¿Es posible devolver 2 (o más) artículos para cada artículo en una lista de comprensión?

Lo que quiero (ejemplo):

[f(x), g(x) for x in range(n)]

debe devolver [f(0), g(0), f(1), g(1), ..., f(n-1), g(n-1)]

Entonces, algo para reemplazar este bloque de código:

result = list() for x in range(n): result.add(f(x)) result.add(g(x))


Esta función lambda comprime dos listas en una sola:

zipped = lambda L1, L2: [L[i] for i in range(min(len(L1), len(L2))) for L in (L1, L2)]

Ejemplo:

>>> f = [x for x in range(5)] >>> g = [x*10 for x in range(5)] >>> zipped(f, g) [0, 0, 1, 10, 2, 20, 3, 30, 4, 40]


>>> from itertools import chain >>> f = lambda x: x + 2 >>> g = lambda x: x ** 2 >>> list(chain.from_iterable((f(x), g(x)) for x in range(3))) [2, 0, 3, 1, 4, 4]

Tiempos:

from timeit import timeit f = lambda x: x + 2 g = lambda x: x ** 2 def fg(x): yield f(x) yield g(x) print timeit(stmt=''list(chain.from_iterable((f(x), g(x)) for x in range(3)))'', setup=''gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2'') print timeit(stmt=''list(chain.from_iterable(fg(x) for x in range(3)))'', setup=''gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2'') print timeit(stmt=''[func(x) for x in range(3) for func in (f, g)]'', setup=''gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2'') print timeit(stmt=''list(chain.from_iterable((f(x), g(x)) for x in xrange(10**6)))'', setup=''gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2'', number=20) print timeit(stmt=''list(chain.from_iterable(fg(x) for x in xrange(10**6)))'', setup=''gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2'', number=20) print timeit(stmt=''[func(x) for x in xrange(10**6) for func in (f, g)]'', setup=''gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2'', number=20)

2.69210777094

3.13900787874

1.62461071932

25.5944058287

29.2623711793

25.7211849286


sum( ([f(x),g(x)] for x in range(n)), [] )

Esto es equivalente a [f(1),g(1)] + [f(2),g(2)] + [f(3),g(3)] + ...

También puedes pensar en esto como:

def flatten(list): ... flatten( [f(x),g(x)] for x in ... )

Nota: La forma correcta es usar itertools.chain.from_iterable o la lista doble de comprensión. (No es necesario volver a crear la lista en cada +, por lo tanto, tiene un rendimiento de O (N) en lugar de O (N ^ 2)). Seguiré usando sum(..., []) cuando quiera uno rápido. -liner o estoy apurado, o cuando el número de términos que se combinan es limitado (por ejemplo, <= 10). Es por eso que todavía lo menciono aquí, con esta advertencia. También puede usar tuplas: ((f(x),g(x)) for ...), () (o por el comentario de khachik, teniendo un generador fg (x) que produce una dos tupla).