【发布时间】:2015-10-31 19:15:07
【问题描述】:
文件包含:
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.]
最有效的方法是什么?
【问题讨论】:
-
它们是空格/换行符吗?
文件包含:
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.]
最有效的方法是什么?
【问题讨论】:
你可以使用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 而不是 map。将链与 map 和 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 匹配列表 comp 但使用更少的内存。
对于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
列表 comp 稍微快一点,但再次使用更多内存,如果您打算使用读取拆分方法将所有内容读入内存,则 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 和 map 一样:
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())) 方法。
如果内存也是一个问题,请将其与链结合起来。如果内存是一个问题,链方法的另一个优点是,如果您将整数传递给函数或迭代,您可以直接传递链对象,因此您根本不需要将所有数据保留在内存中。
最后一个小优化是将 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
【讨论】:
with open('yourfile.txt') as f:
your_list = f.read().split()
将其转换为整数。您可以使用列表压缩:
your_list = [int(i) for i in f.read().split()]
当值不能被强制转换时,这可能会导致异常。
【讨论】:
\r...
>>> '1\r\n2'.split() → ['1', '2']
f=open("output.txt","r")
import re
print map(int,re.split(r"\s+",f.read()))
f.close()
您可以使用re.split 将返回一个列表并将map 用于int。
【讨论】:
如果您可以使用 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() 总是返回一个一维数组,当你给空格作为分隔符时,它会忽略额外的空格,包括换行符。
示例/演示 -
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(与列表没有什么不同)没问题,那会更快。
【讨论】:
您可以使用re.findall。
import re
with open(file) as f:
print map(int, re.findall(r'\d+', f.read()))
【讨论】: