Esiste un metodo incorporato per farlo? In caso contrario, come posso farlo senza costi eccessivi?Come si legge una riga a caso da un file in python?
risposta
Non built-in, ma l'algoritmo R(3.4.2)
("Algoritmo Reservoir" di Waterman) dal Knuth di "The Art of Computer Programming" è buono (in una versione molto semplificata):
import random
def random_line(afile):
line = next(afile)
for num, aline in enumerate(afile):
if random.randrange(num + 2): continue
line = aline
return line
Il num + 2
produce la sequenza 2, 3, 4 ... Il randrange
sarà quindi 0 con una probabilità di 1.0/(num + 2)
- e questa è la probabilità con cui dobbiamo sostituire la linea attualmente selezionata (il caso speciale della dimensione del campione 1 dell'algoritmo di riferimento - vedere Il libro di Knuth per la dimostrazione di correttezza == e naturalmente siamo anche nel caso di un "serbatoio" abbastanza piccolo da stare nella memoria; -) ... e precisamente la probabilità con che noi do così.
+1 per la traduzione da MIX a Python – aaronasterling
Questo è il campionamento del serbatoio, giusto? – HenryR
Ho sempre pensato che la funzione 'random.choice()' dovrebbe funzionare su iteratori arbitrari e sequenze, implementando esattamente l'algoritmo di cui sopra. –
Cercare una posizione casuale, leggere una riga e scartarla, quindi leggere un'altra riga. La distribuzione delle linee non sarà normale, ma non sempre è importante.
In particolare, ciò rende impossibile selezionare sempre la prima riga (oltre a selezionare altre linee con una probabilità proporzionale alla lunghezza di ciascuna riga precedente). Anche la mia A non produce una distribuzione normale (sarebbe strano - che cosa significa, quale varianza ?!), ma una uniforme, che sembra un po 'più probabile che soddisfi il significato dell'OP per "random". –
Per superare il problema indicato da @AlexMartelli, scegliere la prima riga nel caso in cui la ricerca casuale porti all'ultima riga. Ma un altro problema qui è che una linea che ha relativamente più parole per altre linee avrà maggiori probabilità di essere selezionata. –
Dipende da cosa intendi per "troppo" sovraccarico. Se è possibile memorizzare un intero file in memoria, qualcosa come
import random
random_lines = random.choice(open("file").readlines())
farebbe il trucco.
import random
lines = open('file.txt').read().splitlines()
myline =random.choice(lines)
print(myline)
Per file molto lungo: cercano di posto a caso nel file basato su di essa la lunghezza e trovare due caratteri di nuova riga dopo la posizione (o di nuova riga e la fine del file). Ripeti 100 caratteri prima o dall'inizio del file se la posizione di ricerca originale era < 100 se finivamo all'interno dell'ultima riga.
Tuttavia questa è finita complicato, come file è iterator.So renderlo lista e prendere random.choice (se avete bisogno di molti, l'uso random.sample):
import random
print(random.choice(list(open('file.txt'))))
Se l'attività è di leggere solo una riga, non ha senso caricare il file completo in memoria. – iankit
Anche se sono quattro anni di ritardo, Penso di avere la soluzione più veloce. Recentemente ho scritto un pacchetto python chiamato linereader, che consente di manipolare i puntatori degli handle di file.
Qui è la soluzione semplice per ottenere una riga a caso con questo pacchetto:
from random import randint
from linereader import dopen
length = #lines in file
filename = #directory of file
file = dopen(filename)
random_line = file.getline(randint(1, length))
La prima volta che questo viene fatto è il peggiore, come linereader deve compilare il file di output in un formato speciale. Al termine, il linereader può accedere rapidamente a qualsiasi riga del file, indipendentemente dalle dimensioni del file.
Se il file è molto piccolo (abbastanza piccolo da contenere un MB), è possibile sostituire dopen
con copen
e memorizza una voce memorizzata nella cache del file. Non solo è più veloce, ma ottieni il numero di linee all'interno del file mentre viene caricato in memoria; è fatto per te Tutto quello che devi fare è generare il numero di riga casuale. Ecco alcuni esempi di codice per questo.
from random import randint
from linereader import copen
file = copen(filename)
lines = file.count('\n')
random_line = file.getline(randint(1, lines))
mi ha regalato molto contento perché ho visto qualcuno che potrebbe trarre beneficio dal mio pacchetto! Ci scusiamo per la risposta senza risposta, ma il pacchetto potrebbe sicuramente essere applicato a molti altri problemi.
Ho avuto la riga di errore ValueError. non trovato, ma linea no. era inferiore alle dimensioni del file. – kakarukeys
Se non si desidera leggere l'intero file, è possibile cercare nel mezzo del file, quindi cercare all'indietro la nuova riga e chiamare readline
.
Ecco uno script python3 che fa solo questo,
Uno svantaggio di questo metodo è brevi linee hanno una minore probabilita di presentarsi.
def read_random_line(f, chunk_size=16):
import os
import random
with open(f, 'rb') as f_handle:
f_handle.seek(0, os.SEEK_END)
size = f_handle.tell()
i = random.randint(0, size)
while True:
i -= chunk_size
if i < 0:
chunk_size += i
i = 0
f_handle.seek(i, os.SEEK_SET)
chunk = f_handle.read(chunk_size)
i_newline = chunk.rfind(b'\n')
if i_newline != -1:
i += i_newline + 1
break
if i == 0:
break
f_handle.seek(i, os.SEEK_SET)
return f_handle.readline()
È possibile aggiungere le righe in un set() che cambierà il loro ordine casuale.
filename=open("lines.txt",'r')
f=set(filename.readlines())
filename.close()
Per trovare la prima riga:
print(next(iter(f)))
Per trovare la linea 3:
print(list(f)[2])
per elencare tutte le linee del set:
for line in f:
print(line)
Questo potrebbe essere ingombrante, ma funziona credo? (almeno per i file txt)
import random
choicefile=open("yourfile.txt","r")
linelist=[]
for line in choicefile:
linelist.append(line)
choice=random.choice(linelist)
print(choice)
Legge ogni riga di un file e lo aggiunge a un elenco. Quindi sceglie una linea casuale dall'elenco. Se si desidera rimuovere la linea una volta che è scelto, solo che
linelist.remove(choice)
Spero che questo può aiutare, ma almeno nessuno moduli aggiuntivi e le importazioni (a parte casuale) e relativamente leggeri.
- 1. Come si legge un file gzip riga per riga?
- 2. Come si legge esattamente una riga?
- 3. Come si legge l'ennesima riga di un file e lo si stampa su un nuovo file?
- 4. Come si legge da un file nella stessa directory?
- 5. Come si legge un file che si aggiorna costantemente?
- 6. Come si legge un file riga per riga in VB Script?
- 7. Come si legge una riga completa dall'utente usando cin?
- 8. phantomjs javascript legge un file locale riga per riga
- 9. Come ottenere una riga a caso di un file di testo in Java?
- 10. python che legge un file separato da tabulazione usando delimitatore
- 11. Come si carica un file .txt in PHP e si legge riga per riga su un'altra pagina?
- 12. Può Python rimuovere le virgolette doppie da una stringa, quando si legge nel file di testo?
- 13. Come si legge un file che è in uso?
- 14. Come si legge un database di Foxpro 8.0 da C#?
- 15. Come si legge un file binario tramite HTTP nel nodo?
- 16. Come si fa rotta stdin da un file a una funzione quando si esegue GHCI
- 17. Come si comprime/decomprime in modo trasparente un file mentre un programma scrive/legge da esso?
- 18. Voglio leggere un file dalla riga di comando in python
- 19. Come si legge in più file .txt in R?
- 20. Perché $ {fh} si comporta in modo diverso da $ fh quando legge riga per riga?
- 21. Python - legge una precedente variabile "elenco" dal file
- 22. legge un file in una serie di linee in d
- 23. legge l'input da un file e sincronizza di conseguenza
- 24. Come importare un file Python settings.py in un file Python da una sottodirectory?
- 25. Come si scrive/legge su una smartcard?
- 26. Python scrive riga per riga in un file di testo
- 27. Come si legge/scrive un dispositivo a blocchi?
- 28. PHPExcel - legge l'ultima riga
- 29. C: legge solo l'ultima riga di un file. No loop
- 30. Come eseguire una funzione a caso in Python 2
@Greg Questo è Perl, non Python – quantumSoup
@quantumSoup: la domanda usa Perl nei suoi esempi, ma la domanda è indipendente dal linguaggio. Le risposte più utili usano lo pseudocodice, facilmente traducibile nella tua lingua preferita. –
Grazie, ho trovato molto aiuto anche questo: http://mail.python.org/pipermail/tutor/2007-July/055635.html Devi leggerli in memoria però. – Shane