2012-06-20 7 views
6

Esiste una soluzione pitonica per eliminare i valori n da un iteratore? È possibile farlo da solo scartando n valori come segue:Soluzione pitonica per eliminare N valori da un iteratore

def _drop(it, n): 
    for _ in xrange(n): 
     it.next() 

ma questo non è IMO elegante come codice Python dovrebbe essere. C'è un approccio migliore che mi manca qui?

+2

L'utilizzo di 'next (it)' è migliore. – jamylak

+1

@jamylak Non con Python <2.6;) – schlamar

risposta

8

Credo che si sta cercando la ricetta "consumare"

http://docs.python.org/library/itertools.html#recipes

def consume(iterator, n): 
    "Advance the iterator n-steps ahead. If n is none, consume entirely." 
    # Use functions that consume iterators at C speed. 
    if n is None: 
     # feed the entire iterator into a zero-length deque 
     collections.deque(iterator, maxlen=0) 
    else: 
     # advance to the empty slice starting at position n 
     next(islice(iterator, n, n), None) 

Se non è necessario il comportamento speciale quando n è None, si può semplicemente utilizzare

next(islice(iterator, n, n), None) 
+0

'# Utilizzare le funzioni che consumano gli iteratori alla velocità C.' Cosa significa questo? –

+0

@Burhan: un numero di funzioni/tipi in CPython sono implementati in codice C anziché in Python. Di solito sono più veloci degli equivalenti di Python. –

+0

@BurhanKhalid Sono stati scritti in codice C in modo che funzionino alla massima velocità possibile. Il codice Python di solito è più lento. – jamylak

3

È possibile creare una sezione iterativa che inizia dall'elemento n:

import itertools 
def drop(it, n): 
    return itertools.islice(it, n, None) 
+1

Anche se intelligente, questo in realtà non rilascia nulla fino a/* a meno che * la sequenza non venga ripetuta. –

+0

Vero, dipende da ciò di cui ha bisogno. Quando è effettivamente caduto potrebbe non avere importanza per lui. – ThiefMaster

0

Si potrebbe fare questo con l'uso di fantasia di itertools.dropwhile, ma io esiterei a chiamarlo in alcun modo elegante:

def makepred(n): 
    def pred(x): 
     pred.count += 1 
     return pred.count < n 
    pred.count = 0 
    return pred 

itertools.dropwhile(it, makepred(5)) 

davvero non consiglio questo, anche se - basandosi su gli effetti collaterali di una funzione di predicato sono molto sul lato dispari.

Problemi correlati