2009-12-17 11 views
100

Tengo una lista de latitudes y una de longitudes y necesito iterar sobre los pares de latitud y longitud.¿Hay una mejor manera de iterar en dos listas, obteniendo un elemento de cada lista para cada iteración?

¿Qué es mejor:

  • A. Supongamos que las listas son de la misma longitud:

    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]: 
    

(Tenga en cuenta que B es incorrecto. Esto me da todos los pares, equi valent a itertools.product())

¿Alguna idea de los méritos relativos de cada uno, o que es más pitonica?

Respuesta

197

Esto es como Pythonic como se puede llegar:

for lat, long in zip(Latitudes, Longitudes): 
    print lat, long 
+24

En Python 2.x puede considerar itertools.izip en su lugar (zip hace lo mismo en Python 3.x). –

+2

@NicholasRiley: cuidado de mencionar por qué? – User

+5

Usa menos memoria y puede ser más rápido; crea un iterador en lugar de una lista intermedia. –

6

Iterar a través de elementos de dos listas al mismo tiempo que se conoce como comprimir y Python proporciona una función integrada para ello, que se documenta here.

>>> 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 se toma de pydocs]

En su caso, será simplemente:

for (lat, lon) in zip(latitudes, longitudes): 
    ... process lat and lon 
5
for Lat,Long in zip(Latitudes, Longitudes): 
20

bueno ver a un montón de amor por zip en las respuestas aquí.

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

En python 3 y posterior zip se comporta como izip.

39

Otra forma de hacerlo sería usando 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 de las diferencias en el uso de un mapa en comparación con zip es, la cremallera de la longitud de la nueva lista es
misma 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 

en el mapa en el mismo los datos:

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

    1 4 
    2 5 
    3 6 
    9 None 
+0

¿es posible hacerlo como: 14,15,16? – BomberMan

15

en caso de que sus listas de latitud y longitud son grandes y cargados de forma liviana:

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

o si se quiere evitar el for-loop

from itertools import izip, imap 
out = imap(process, izip(latitudes, longitudes)) 
3

Esta publicación me ayudó con zip(). Sé que llegué unos años tarde, pero todavía quiero contribuir. Esto está 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 3.x pitón

ya que parece que usted está construyendo una lista de tuplas, el siguiente código es la forma más Pythonic de tratar de lograr lo que está haciendo.

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

O, de forma alternativa, puede utilizar list comprehensions (o list comps) en caso de necesitar operaciones más complicadas. Las comprensiones de listas también se ejecutan tan rápido como map(), dan o toman unos nanosegundos, y se están convirtiendo en la nueva norma para lo que se considera Pythonic 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] 
Cuestiones relacionadas