una - string en python
Manera pitónica para dividir números separados por comas en pares (5)
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 pitónico ?
¿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.
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.
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 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 Recipes 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 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.
Una solución muy parecida a FogleBirds, pero usando un iterador (una expresión generadora) en lugar de una comprensión de 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ían bastante "pitónicas".