2015-07-29 6 views
7

Ho una lista di elementi in python. Non conosco il numero di elementi nell'elenco. Vorrei aggiungere indici alla lista.Equivalente Python di Haskell [1 ..] (per indicizzare una lista)

In Haskell, ho potuto effettuare le seguenti operazioni

zip [1..] "abcdefghijklmnop" 
[(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(9,'i'),(10,'j'),(11,'k'),(12,'l'),(13,'m'),(14,'n'),(15,'o'),(16,'p')] 

Ora immaginate che la stringa era di dimensioni sconosciute. Ciò funzionerebbe ancora in Haskell e l'elenco intero fornisce tutti gli interi numeri necessari fino a quando la stringa non si esaurisce.

Come si può fare l'equivalente in Python?

Ho provato questo:

s = "abcdefghijklmnop" 
indexedlist = [] 
for i,c in enumerate(s): 
    indexedlist.append((i,c)) 

>>> indexedlist 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h'), (8, 'i'), (9, 'j'), (10, 'k'), (11, 'l'), (12, 'm'), (13, 'n'), (14, 'o'), (15, 'p')] 

e funziona, ma mi chiedo se c'è un modo più breve/più pulito, dal momento che è di 4 righe di codice e si sente molto.

+2

BTW: si probabilmente vuoi: 'enumerate (s, start = 1)' per un equivalente diretto. Inoltre nel modulo 'itertools' c'è un equivalente perfetto di' [n ..] 'che è' itertools.count (n) 'in modo da poter tradurre il codice in' zip (count (n), s) '. – Bakuriu

+0

Per il tuo n, non metteresti realmente len (s) quando non conosci n? – user985366

+0

No. 'count (n)' è "lo stesso" di '[n ..]' vale a dire la sequenza infinita di naturali maggiore o uguale a 'n'. – Bakuriu

risposta

21

Basta fare list(enumerate(s)). Questo esegue l'iterazione dell'oggetto enumerate e lo converte in list.

+0

Credo che questo sia il più pulito finora, anche se funzionano tutti. Funziona anche per me su Python 2.7 – user985366

1

È possibile utilizzare la funzione range con zip.

Per Python 2:

>>> s = "abcdefghijklmnop" 
>>> zip(range(16),s) 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h'), (8, 'i'), (9, 'j'), (10, 'k'), (11, 'l'), (12, 'm'), (13, 'n'), (14, 'o'), (15, 'p')] 

Per Python 3:

>>> s = "abcdefghijklmnop" 
>>> list(zip(range(16),s)) 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h'), (8, 'i'), (9, 'j'), (10, 'k'), (11, 'l'), (12, 'm'), (13, 'n'), (14, 'o'), (15, 'p')] 
+0

NB: Questo funziona solo in Python 2, dove 'zip()' restituisce un 'elenco' . – TigerhawkT3

+0

Poiché (in Python 3) 'zip (intervallo (len (s)), s' è identicamente funzionante a' enumerate (s) ', sembra che tu sia arrivato a' lista (enumerare (i)) '.: P – TigerhawkT3

+0

Sì, è giusto – Brien

5

È possibile semplificare con una lista di comprensione:

>>> [i for i in enumerate(s)] 
1

Utilizzando enumerate è sicuramente la strada da percorrere, ma qui è la soluzione un po 'più funzionale con toolz:

from toolz.itertoolz import iterate, zip 
zip(iterate(lambda x: x + 1, 0), "abcdefghijklmnop") 
+0

Puoi sostituire la chiamata 'iterate' con' itertools.count (0) '. .. – Bakuriu