2009-05-15 12 views
17

mi piacerebbe dividere un valore separato da virgole in coppie:modo Pythonic di dividere i numeri separati da 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 ti rilevare e gestire una stringa con un set dispari di numeri?

+0

possibile duplicato di [Come si divide una lista in blocchi di dimensioni uguali in Python?] (Http://stackoverflow.com/questions/312443/how-do-you-split-a-list-into-evenly- dimensioni-pezzi-in-python) – tzot

risposta

44

Qualcosa di simile:

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

esempio completa:

>>> 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. Verranno incluse solo le coppie complete.

+13

Dio che amo Python ... – 0x6adb015

8

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')] 

Questo 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. Ci sono due domande molto simili a StackOverflow su questo:

C'è anche questo gioiello dalla sezione Recipes 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) 
+0

Non ho pensato di cercare il chunk – jsamsa

2

Questo ignorerà l'ultima numero in una strana lista:

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

Questa volontà 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.

+0

o con il Python "crippled" 2.5: se len (r)% 2: r.append (0) –

8

Un'opzione 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.

+1

questo criptico al livello successivo – YGA

+0

Esp. la duplicazione della parte iteratore. ;-) Cool, tuttavia. – Plumenator

4

Una soluzione molto simile a FogleBirds, ma utilizzando un iteratore (un generatore di espressione), invece di comprensione 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) 

Entrambe le espressioni di lista e le espressioni di generatore sarebbero probabilmente considerate piuttosto "pythonic".

+1

Questo aiuta a comprendere il codice di Ants Aasma. – Plumenator

Problemi correlati