【问题标题】:Creating List From File In Python在 Python 中从文件创建列表
【发布时间】: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.]

最有效的方法是什么?

【问题讨论】:

  • 它们是空格/换行符吗?

标签: python list file


【解决方案1】:

你可以使用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

【讨论】:

    【解决方案2】:
    with open('yourfile.txt') as f:
        your_list = f.read().split()
    

    将其转换为整数。您可以使用列表压缩:

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

    当值不能被强制转换时,这可能会导致异常。

    【讨论】:

    • 顺便说一句:这种方法适用于中小型文件。
    • @vks 默认拆分在空格和换行处拆分。但我必须测试\r...
    • 在 Python 2 和 3 中:>>> '1\r\n2'.split()['1', '2']
    【解决方案3】:
    f=open("output.txt","r")
    import re
    print map(int,re.split(r"\s+",f.read()))
    f.close()
    

    您可以使用re.split 将返回一个列表并将map 用于int

    【讨论】:

      【解决方案4】:

      如果您可以使用 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(与列表没有什么不同)没问题,那会更快。

      【讨论】:

        【解决方案5】:

        您可以使用re.findall

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-12-19
          • 2023-03-22
          • 2018-09-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-08
          相关资源
          最近更新 更多