¿Hay una mejor manera de iterar sobre dos listas, obteniendo un elemento de cada lista para cada iteración? [duplicar]


Esta pregunta ya tiene una respuesta aquí:

Tengo una lista de Latitudes y una de Longitudes y necesito iterar sobre los pares de latitud y longitud.

Es mejor:

  • A. Asumir que las listas son de igual longitudes:

    for i in range(len(Latitudes):
        Lat,Long=(Latitudes[i],Longitudes[i])
    
  • B. O:

    for Lat,Long in [(x,y) for x in Latitudes for y in Longitudes]:
    

(Nótese que B es incorrecta. Esto me da todos los pares, equivalentes a itertools.product())

¿Algún pensamiento sobre los méritos relativos de cada uno, o cuál es más pitónico?

Author: Nathaniel Ford, 2009-12-17

7 answers

Esto es lo más pitónico que puedes conseguir:

for lat, long in zip(Latitudes, Longitudes):
    print lat, long
 215
Author: Roberto Bonvallet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-17 02:03:39

Otra forma de hacer esto sería usar map.

>>> a
[1, 2, 3]
>>> b
[4, 5, 6]
>>> for i,j in map(None,a,b):
    ...   print i,j
    ...
1 4
2 5
3 6

Una diferencia en el uso de mapa en comparación con zip es, con zip la longitud de la nueva lista es
igual que la longitud de la lista más corta. Por ejemplo:

>>> a
[1, 2, 3, 9]
>>> b
[4, 5, 6]
>>> for i,j in zip(a,b):
    ...   print i,j
    ...
1 4
2 5
3 6

Usando el mapa en los mismos datos:

>>> for i,j in map(None,a,b):
    ...   print i,j
    ...

    1 4
    2 5
    3 6
    9 None
 44
Author: sateesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-12 20:30:55

Es bueno ver mucho amor por zip en las respuestas aquí.

Sin embargo, debe tenerse en cuenta que si está utilizando una versión de python anterior a la 3.0, el módulo itertools en la biblioteca estándar contiene una función izip que devuelve un iterable, que es más apropiado en este caso (especialmente si su lista de latt/longs es bastante larga).

En python 3 y posteriores zip se comporta como izip.

 21
Author: Wogan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-17 02:10:49

En caso de que sus listas de Latitud y longitud sean grandes y estén cargadas perezosamente:

from itertools import izip
for lat, lon in izip(latitudes, longitudes):
    process(lat, lon)

O si desea evitar el bucle for

from itertools import izip, imap
out = imap(process, izip(latitudes, longitudes))
 15
Author: JudoWill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-17 04:54:35

Iterar a través de elementos de dos listas simultáneamente se conoce como comprimir, y python proporciona una función incorporada para ello, que se documenta aquí.

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x == list(x2) and y == list(y2)
True

[Ejemplo tomado de pydocs]

En su caso, será simplemente:

for (lat, lon) in zip(latitudes, longitudes):
    ... process lat and lon
 6
Author: notnoop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-15 21:10:00
for Lat,Long in zip(Latitudes, Longitudes):
 5
Author: John La Rooy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-17 02:04:16

Este post me ayudó con zip(). Sé que estoy un par de años tarde, pero todavía quiero contribuir. Esto es en Python 3.

Nota: en python 2.x, zip() devuelve una lista de tuplas; en Python 3.x, zip() devuelve un iterador. itertools.izip() en python 2.x = = zip() en python 3.x

Dado que parece que estás construyendo una lista de tuplas, el siguiente código es la forma más pitónica de intentar lograr lo que estás haciendo.

>>> lat = [1, 2, 3]
>>> long = [4, 5, 6]
>>> tuple_list = list(zip(lat, long))
>>> tuple_list
[(1, 4), (2, 5), (3, 6)]

O, alternativamente, puede usar list comprehensions (o list comps) si necesita operaciones más complicadas. Las comprensiones de listas también corren tan rápido como map(), más o menos unos pocos nanosegundos, y se están convirtiendo en la nueva norma para lo que se considera Pitónico versus map().

>>> lat = [1, 2, 3]
>>> long = [4, 5, 6]
>>> tuple_list = [(x,y) for x,y in zip(lat, long)]
>>> tuple_list
[(1, 4), (2, 5), (3, 6)]
>>> added_tuples = [x+y for x,y in zip(lat, long)]
>>> added_tuples
[5, 7, 9]
 3
Author: dysfunctional,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-28 15:31:58