2015-08-08 2 views
7

Файл содержит:Создание списка из файла в Python

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

От что я хотел бы извлечь список следующим образом:

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

Что является наиболее эффективным способом сделать это?

+0

Разделяются ли они пробелами/символами новой строки? –

ответ

5

Вы можете использовать itertools.chain, разделив каждую строку и отображение на Интс:

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] 

Для использования python2 itertools.imap вместо карты. используя цепочку с картой и itertools.chain избегает сразу считывать весь файл в память, что будет делать .read.

Некоторые тайминги для Python3 на файл такой же, как ваш вклад * 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 

Так itertools соответствует списку комп, но использует намного меньше памяти.

Для 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 

Список Комп немного быстрее, но опять использует больше памяти, если вы собираетесь читать все в памяти с чтения расколоть подход IMAP снова самый быстрый:

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 

То же самое для Python3 и карты:

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 

Так что, если скорость все, что вы заботитесь о используйте подход list(map(int,f.read().split())) или list(imap(int,f.read().split())).
Если память также вызывает беспокойство, объедините ее с цепью. Еще одно преимущество цепного подхода, если память вызывает беспокойство, - если вы передаете функции int или выполняете итерацию, вы можете передать объект цепи напрямую, чтобы вам не нужно было хранить все данные в памяти вообще.

последнее небольшая оптимизация является отображение str.split на объекте файла:

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() 

Вы можете использовать re.split, которая будет возвращать список и map в int.

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

Чтобы передать его в целое число. Вы можете использовать список:

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

Это может привести к исключению, если значение не может быть выполнено.

+0

BTW: Этот подход подходит для небольших и средних файлов. –

+0

@vks Разделение по умолчанию разбивается на пробелы и символы новой строки. Но я должен проверить на '\ r' ... –

+0

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

0

Вы можете использовать re.findall.

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

Если все в порядке с использованием numpy библиотеки, другой метод будет использовать np.fromstring() давая файла .read() в качестве вклада в него, пример -

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

В конце lst будет NumPy массив , если вы хотите список python, используйте list(lst)

numpy.fromstring()numpy.fromstring() всегда возвращает 1D массив, и когда вы предоставляете пространство в качестве разделителя, оно будет игнорировать дополнительные пробелы , которые включают в себя новые строки.


Пример/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] 

Тестирование производительности -

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 

Если вы хорошо с numpy.ndarray (что не сильно отличается от списка), который был бы Быстрее.

Смежные вопросы