2015-08-08 9 views
7

Il file contiene:Creazione Lista Da file In Python

1 19 15 36 23 18 39 
2 36 23 4 18 26 9 
3 35 6 16 11 

Da che mi piacerebbe per estrarre l'elenco come segue:

L = [1,19,15,36,23,18,19,2,36........... ect.] 

Qual è il modo più efficace per farlo?

+0

Sono separati spazi/nuove righe? –

risposta

5

È possibile utilizzare itertools.chain, dividendo ogni linea e la mappatura di interi:

from itertools import chain 
with open("in.txt") as f: 
    print(list((map(int,chain.from_iterable(line.split() for line in f))))) 
[1, 19, 15, 36, 23, 18, 39, 2, 36, 23, 4, 18, 26, 9, 3, 35, 6, 16, 11] 

Per uso python2 itertools.imap invece di carta. utilizzando la catena con la mappa e itertools.chain evita di leggere tutti i file in memoria in una volta, il che è ciò che farà .read.

Alcune tempi per python3 su un file lo stesso come ingresso * 1000:

In [5]: %%timeit 
with open("ints.txt","r") as f: 
    list(map(int,re.split(r"\s+",f.read()))) 
    ...: 
100 loops, best of 3: 8.55 ms per loop 

In [6]: %%timeit             
with open("ints.txt","r") as f: 
    list((map(int, chain.from_iterable(line.split() for line in f)))) 
    ...: 
100 loops, best of 3: 5.76 ms per loop 

In [7]: %%timeit 
...: with open("ints.txt","r") as f: 
...:  [int(i) for i in f.read().split()] 
...: 
100 loops, best of 3: 5.82 ms per loop 

Così itertools corrisponde all'elenco comp ma usa molta meno memoria.

Per python2:

In [3]: %%timeit             
with open("ints.txt","r") as f: 
    [int(i) for i in f.read().split()] 
    ...: 
100 loops, best of 3: 7.79 ms per loop 

In [4]: %%timeit             
with open("ints.txt","r") as f: 
    list(imap(int, chain.from_iterable(line.split() for line in f))) 
    ...: 
100 loops, best of 3: 8.03 ms per loop 

In [5]: %%timeit             
with open("ints.txt","r") as f: 
    list(imap(int,re.split(r"\s+",f.read()))) 
    ...: 
100 loops, best of 3: 10.6 ms per loop 

La lista comp è marginalmente più veloce, ma ancora una volta utilizza più memoria, se si andavano a leggere tutto in memoria con la lettura dividere approccio IMAP è di nuovo il più veloce:

In [6]: %%timeit 
    ...: with open("ints.txt","r") as f: 
    ...:  list(imap(int, f.read().split())) 
    ...: 
100 loops, best of 3: 6.85 ms per loop 

Lo stesso vale per python3 e mappa:

In [4]: %%timeit             
with open("ints.txt","r") as f: 
    list(map(int,f.read().split())) 
    ...: 
100 loops, best of 3: 4.41 ms per loop 

Quindi, se la velocità è tutto ciò che interessa utilizzare l'approccio list(map(int,f.read().split())) o list(imap(int,f.read().split())).
Se anche la memoria è una preoccupazione, combinala con la catena. Un altro vantaggio dell'approccio a catena se la memoria è un problema è che se si passano gli interi a una funzione o si scorre su di essa è possibile passare direttamente l'oggetto catena in modo tale che non sia necessario conservare tutti i dati in memoria.

Un ultimo piccolo ottimizzazione è quello di mappare str.split sul oggetto file:

In [5]: %%timeit 
with open("ints.txt", "r") as f: 
    list((map(int, chain.from_iterable(map(str.split, f))))) 
    ...: 
100 loops, best of 3: 5.32 ms per loop 
2
f=open("output.txt","r") 
import re 
print map(int,re.split(r"\s+",f.read())) 
f.close() 

È possibile utilizzare re.split che restituirà una lista e map a int.

3
with open('yourfile.txt') as f: 
    your_list = f.read().split() 

Per trasmettere un numero intero. È possibile utilizzare una compregension di elenchi:

your_list = [int(i) for i in f.read().split()] 

Ciò potrebbe causare un'eccezione quando il valore non può essere convertito.

+0

BTW: Questo è un approccio valido per file di piccole e medie dimensioni. –

+0

@vks Il divario predefinito suddivide a spazi e a capo. Ma devo provare a '\ r' ... –

+0

In Python 2 e 3:' >>> '1 \ r \ n2'.split() '→' [' 1 ',' 2 '] ' –

0

È possibile utilizzare re.findall.

import re 
with open(file) as f: 
    print map(int, re.findall(r'\d+', f.read())) 
1

Se si sta bene con l'utilizzo di numpy biblioteca, un altro metodo sarebbe quello di utilizzare np.fromstring() dando del .read() come input ad esso di file, Esempio -

import numpy as np 
with open('file.txt','r') as f: 
    lst = np.fromstring(f.read(),sep=' ',dtype=int) 

Alla fine lst sarebbe una matrice numpy , se si desidera un elenco di pitone, utilizzare list(lst)

numpy.fromstring() restituisce sempre una matrice 1D, e quando si dà spazio come separatore, ignorerà spazi bianchi in più , che include i newline.


Esempio/Demo -

In [39]: import numpy as np 

In [40]: with open('a.txt','r') as f: 
    ....:  lst = np.fromstring(f.read(),sep=' ',dtype=int) 
    ....: 

In [41]: lst 
Out[41]: 
array([ 1, 19, 15, 36, 23, 18, 39, 2, 36, 23, 4, 18, 26, 9, 3, 35, 6, 
     16, 11]) 

In [42]: list(lst) 
Out[42]: [1, 19, 15, 36, 23, 18, 39, 2, 36, 23, 4, 18, 26, 9, 3, 35, 6, 16, 11] 

Performance Testing -

In [47]: def func1(): 
    ....:  with open('a.txt','r') as f: 
    ....:   lst = np.fromstring(f.read(),sep=' ',dtype=int) 
    ....:   return list(lst) 
    ....: 
In [37]: def func2(): 
    ....:  with open('a.txt','r') as f: 
    ....:   return list((map(int,chain.from_iterable(line.split() for line in f)))) 
    ....: 

In [54]: def func3(): 
    ....:  with open('a.txt','r') as f: 
    ....:   return np.fromstring(f.read(),sep=' ',dtype=int) 
    ....: 

In [55]: %timeit func3() 
10000 loops, best of 3: 183 µs per loop 

In [56]: %timeit func1() 
10000 loops, best of 3: 194 µs per loop 

In [57]: %timeit func2() 
10000 loops, best of 3: 212 µs per loop 

Se siete daccordo con numpy.ndarray (che non è molto diverso dalla lista), che sarebbe Più veloce.