2016-01-30 17 views
5

Sto cercando di ottenere più nomi separati da newline dalla console e di inserirli in una variabile. Supponiamo di voler ottenere input dal terminale per sempre (aggiungerò del codice per uscire dal ciclo successivo). So come farlo con un ciclo while e ricorsione, ma mi piacerebbe essere in grado di farlo con un ciclo for.Python esegue iterate su stdin linea per riga utilizzando input()

Nell'esempio che segue quando arrivo "peter" come input dal terminale ottengo ogni lettera invece che di un'intera riga alla volta:

for name in input(): 
    print(name) 

Ora, se uso sys.stdin variabile name diventa "peter\n":

for name in sys.stdin: 
    print(name) 

c'è un modo facile per ottenere input() per dare "name" un'intera linea, piuttosto che singoli caratteri? O semplicemente per la natura dell'uso di for in Sto andando a scorrere tra i caratteri nell'input? Ci sono dei rischi/problemi inerenti all'entrare in questo modo? Esiste un modo "standard" per ottenere input in una situazione come questa?

Sto usando Python 3.5.1 su Ubuntu 15.10.

+0

'input()' restituisce una stringa che è iterabile, quindi quando si prova e si itera su di esso si ottengono i singoli caratteri uno per uno. –

+0

Ok questo ha senso. input() restituisce una stringa. Quindi sys.stdin restituisce un buffer che viene iterato riga per riga? – PeterH

+0

Perché sys.stdin restituisce un file come oggetto che, quando viene iterato, conterrà ogni singola riga dell'input. –

risposta

5

Puoi avvolgere stdin mettere a nudo i ritorni a capo; se si può spogliare tutti gli spazi finali (di solito va bene), poi è solo:

for name in map(str.rstrip, sys.stdin): 
    ... 

Sei in PY3, in modo che funziona così com'è; se sei su Py2, dovrai aggiungere un'importazione, from future_builtins import map, in modo da ottenere un generatore pigro, basato su map (che produce le linee quando vengono richieste, piuttosto che borbottare stdin fino alla fine, quindi restituire un list di tutte le linee).

Se è necessario limitare a ritorni a capo, un generatore di espressione può farlo:

for name in (line.rstrip("\r\n") for line in sys.stdin): 
    ... 

o con un'importazione per consentire map a spingere lavoro per C layer per (leggermente) il codice più velocemente (una questione di 30 nanosecondi -Alcuni per linea più veloce rispetto al genexpr, ma ancora 40 ns per linea più lento rispetto l'opzione argumentless nella parte superiore di questa risposta):

from operator import methodcaller 

for name in map(methodcaller('rstrip', '\r\n'), sys.stdin): 
    ... 

Come la prima soluzione, in PY2, assicurarsi di ottenere il map da future_builtins.

0

io non consiglierei questo, ma è possibile creare un generatore da utilizzare in un ciclo for per scorrere attraverso la linea di input per riga:

def getlines(): 
    while True: 
     yield input() 

for name in getlines(): 
    print(name) 
    ## Remember to break out of the loop at some point 
+0

Scusa se non sono stato chiaro. Sto provando a farlo più di una volta con ogni nome separato da una nuova riga nel terminale. – PeterH

+0

@PeterH Ho aggiornato la mia risposta –