guia - Idioma de Python "Todos los demás elementos"
qgis manual (8)
¿Qué hay de usar la función de paso de range()
:
[(l[n],l[n+1]) for n in range(0,len(l),2)]
Siento que paso mucho tiempo escribiendo código en Python, pero no tengo suficiente tiempo para crear código Pythonic. Recientemente me encontré con un pequeño problema divertido que pensé que podría tener una solución fácil e idiomática. Parafraseando el original, necesitaba recolectar cada par secuencial en una lista. Por ejemplo, dada la lista [1,2,3,4,5,6]
, quería calcular [(1,2),(3,4),(5,6)]
.
Se me ocurrió una solución rápida en ese momento que parecía traducida como Java. Revisando la pregunta, lo mejor que podía hacer era
l = [1,2,3,4,5,6]
[(l[2*x],l[2*x+1]) for x in range(len(l)/2)]
que tiene el efecto secundario de arrojar el último número en el caso de que la longitud no sea pareja.
¿Hay un enfoque más idiomático del que me estoy perdiendo, o es esto lo mejor que voy a obtener?
El que se cita a menudo es:
zip(*[iter(l)] * 2)
Esto lo hará un poco más claramente:
>>> data = [1,2,3,4,5,6]
>>> zip(data[0::2], data[1::2])
[(1, 2), (3, 4), (5, 6)]
(pero podría decirse que es menos legible si no está familiarizado con la función "zancada" de los rangos).
Al igual que su código, descarta el último valor donde tiene un número impar de valores.
Lo correcto es probablemente no calcular listas, sino escribir una función iterador-> iterador. Esto es más genérico: funciona en todos los iterables, y si desea "congelarlo" en una lista, puede usar la función "list ()".
def groupElements(iterable, n):
# For your case, you can hardcode n=2, but I wanted the general case here.
# Also, you do not specify what to do if the
# length of the list is not divisible by 2
# I chose here to drop such elements
source = iter(iterable)
while True:
l = []
for i in range(n):
l.append(source.next())
yield tuple(l)
Me sorprende que el módulo itertools ya no tenga una función para eso, tal vez una futura revisión. Hasta entonces, siéntete libre de usar la versión anterior :)
Normalmente copio la receta del grouper
de la documentación de itertools en mi código para esto.
def grouper(n, iterable, fillvalue=None):
"grouper(3, ''ABCDEFG'', ''x'') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
Si no quiere perder elementos si su número en la lista no es siquiera, intente esto:
>>> l = [1, 2, 3, 4, 5]
>>> [(l[i], l[i+1] if i+1 < len(l) else None) for i in range(0, len(l), 2)]
[(1, 2), (3, 4), (5, None)]
prueba esto
def pairs(l, n):
return zip(*[l[i::n] for i in range(n)])
Asi que,
pairs([1, 2, 3, 4], 2)
da
[(1, 2), (3, 4)]