Manera pythonica para dividir números separados por comas en pares

Me gustaría dividir un valor separado por comas en pares:

>>> s = '0,1,2,3,4,5,6,7,8,9' >>> pairs = # something pythonic >>> pairs [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] 

¿Cómo se vería # algo pythonico ?

¿Cómo detectarías y manejarías una cadena con un conjunto impar de números?

Algo como:

 zip(t[::2], t[1::2]) 

Ejemplo completo:

 >>> s = ','.join(str(i) for i in range(10)) >>> s '0,1,2,3,4,5,6,7,8,9' >>> t = [int(i) for i in s.split(',')] >>> t [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> p = zip(t[::2], t[1::2]) >>> p [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)] >>> 

Si el número de elementos es impar, el último elemento se ignorará. Solo se incluirán pares completos.

Una opción más general, que también funciona en los iteradores y permite combinar cualquier número de elementos:

  def n_wise(seq, n): return zip(*([iter(seq)]*n)) 

Reemplace zip con itertools.izip si desea obtener un iterador perezoso en lugar de una lista.

Qué tal esto:

 >>> x = '0,1,2,3,4,5,6,7,8,9'.split(',') >>> def chunker(seq, size): ... return (tuple(seq[pos:pos + size]) for pos in xrange(0, len(seq), size)) ... >>> list(chunker(x, 2)) [('0', '1'), ('2', '3'), ('4', '5'), ('6', '7'), ('8', '9')] 

Esto también manejará muy bien las cantidades desiguales:

 >>> x = '0,1,2,3,4,5,6,7,8,9,10'.split(',') >>> list(chunker(x, 2)) [('0', '1'), ('2', '3'), ('4', '5'), ('6', '7'), ('8', '9'), ('10',)] 

PD: Tenía este código escondido y me di cuenta de dónde lo había sacado. Hay dos preguntas muy similares en stackoverflow sobre esto:

  • ¿Cuál es la forma más “pythonic” de iterar sobre una lista en trozos?
  • ¿Cómo se divide una lista en trozos de tamaño uniforme en Python?

También hay esta joya de la sección de recetas de itertools :

 def grouper(n, iterable, fillvalue=None): "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" args = [iter(iterable)] * n return izip_longest(fillvalue=fillvalue, *args) 

Una solución muy parecida a FogleBirds, pero que usa un iterador (una expresión generadora) en lugar de la comprensión de la lista.

 s = '0,1,2,3,4,5,6,7,8,9' # generator expression creating an iterator yielding numbers iterator = (int(i) for i in s.split(',')) # use zip to create pairs # (will ignore last item if odd number of items) # Note that zip() returns a list in Python 2.x, # in Python 3 it returns an iterator pairs = zip(iterator, iterator) 

Tanto la comprensión de listas como las expresiones generadoras probablemente se considerarán bastante “pythonicas”.

Esto ignorará el último número en una lista impar:

 n = [int(x) for x in s.split(',')] print zip(n[::2], n[1::2]) 

Esto rellenará la lista más corta con 0 en una lista impar:

 import itertools n = [int(x) for x in s.split(',')] print list(itertools.izip_longest(n[::2], n[1::2], fillvalue=0)) 

izip_longest está disponible en Python 2.6.