modo Pythonic dividere virgola numeri separati in coppie
Domanda
Vorrei dividere un valore separato virgola in coppie:
>>> 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)]
Cosa sarebbe # qualcosa divinatorio assomigliare?
Come si rilevare e gestire una stringa con un set dispari di numeri?
Soluzione
Qualcosa di simile:
zip(t[::2], t[1::2])
Esempio 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)]
>>>
Se il numero di elementi è dispari, l'ultimo elemento verrà ignorato. saranno incluse solo coppie completi.
Altri suggerimenti
Una soluzione più generale, che funziona anche su iteratori e permette di combinare qualsiasi numero di elementi:
def n_wise(seq, n):
return zip(*([iter(seq)]*n))
Sostituire zip con itertools.izip se si vuole ottenere un iteratore pigro invece di una lista.
Che ne dite di questo:
>>> 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')]
Questa sarà anche ben gestire quantità irregolari:
>>> 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',)]
P.S. Avevo questo codice messo da parte e ho appena realizzato dove l'ho preso da. Non c'è due domande molto simili a StackOverflow a questo:
- Qual è il modo più “divinatorio” per iterare su una lista in pezzi?
- Come si fa a dividere una lista in blocchi in modo uniforme dimensioni in Python?
C'è anche questo gioiello dalla sezione Ricette di 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 soluzione molto simile a FogleBirds, ma utilizzando un iteratore (un generatore di espressione) anziché di 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)
Sia list comprehension e le espressioni del generatore probabilmente essere considerati abbastanza "divinatorio".
Questo ignorerà l'ultimo numero in una strana lista:
n = [int(x) for x in s.split(',')]
print zip(n[::2], n[1::2])
Questa PAD l'elenco più breve da 0 in una strana lista:
import itertools
n = [int(x) for x in s.split(',')]
print list(itertools.izip_longest(n[::2], n[1::2], fillvalue=0))
izip_longest disponibile in Python 2.6.