【问题标题】:How to save a list to a file and read it as a list type?如何将列表保存到文件并将其作为列表类型读取?
【发布时间】:2015-02-28 23:34:18
【问题描述】:

假设我有列表 score=[1,2,3,4,5] 并且在我的程序运行时它会发生变化。如何将其保存到文件中,以便下次运行程序时可以将更改的列表作为列表类型访问?

我试过了:

score=[1,2,3,4,5]

with open("file.txt", 'w') as f:
    for s in score:
        f.write(str(s) + '\n')

with open("file.txt", 'r') as f:
    score = [line.rstrip('\n') for line in f]


print(score)

但这会导致列表中的元素是字符串而不是整数。

【问题讨论】:

  • 听起来您可能对pickle 模块感兴趣。

标签: python list file python-3.x pickle


【解决方案1】:

您可以为此使用pickle 模块。 这个模块有两个方法,

  1. Pickling(dump):将 Python 对象转换为字符串表示形式。
  2. Unpickling(load):从存储的字符串表示中检索原始对象。

https://docs.python.org/3.3/library/pickle.html

代码

>>> import pickle
>>> l = [1,2,3,4]
>>> with open("test", "wb") as fp:   #Pickling
...   pickle.dump(l, fp)
... 
>>> with open("test", "rb") as fp:   # Unpickling
...   b = pickle.load(fp)
... 
>>> b
[1, 2, 3, 4]

还有Json

  1. 转储/转储:序列化
  2. 加载/加载:反序列化

https://docs.python.org/3/library/json.html

代码

>>> import json
>>> with open("test", "w") as fp:
...     json.dump(l, fp)
...
>>> with open("test", "r") as fp:
...     b = json.load(fp)
...
>>> b
[1, 2, 3, 4]

【讨论】:

【解决方案2】:

我决定不想使用 pickle,因为我希望能够在测试期间打开文本文件并轻松更改其内容。因此,我这样做了:

score = [1,2,3,4,5]

with open("file.txt", "w") as f:
    for s in score:
        f.write(str(s) +"\n")
score = []
with open("file.txt", "r") as f:
  for line in f:
    score.append(int(line.strip()))

因此文件中的项目被读取为整数,尽管作为字符串存储到文件中。

【讨论】:

  • 为什么你认为使用泡菜并不比你的建议容易?
  • @Hadij 他们希望能够在文本编辑器中打开它
【解决方案3】:

虽然接受的答案有效,但您确实应该使用 python 的 json 模块:

import json

score=[1,2,3,4,5]

with open("file.json", 'w') as f:
    # indent=2 is not needed but makes the file human-readable
    json.dump(score, f, indent=2) 

with open("file.json", 'r') as f:
    score = json.load(f)

print(score)

优势

  1. json 是一种被广泛采用和标准化的数据格式,因此非 python 程序可以轻松读取和理解 json 文件
  2. json 文件是人类可读的
  3. 任何嵌套或非嵌套列表/字典结构都可以保存到json 文件中(只要所有内容都是可序列化的)。

缺点

  1. 数据以纯文本形式存储(即未压缩),这使得它对于大量数据来说是一个缓慢而臃肿的选择(即对于存储大型 numpy 数组来说可能是一个糟糕的选择,这就是 hdf5 的用途) .
  2. 列表/字典的内容需要可序列化才能将其保存为 json,因此虽然您可以保存字符串、整数和浮点数等内容,但您需要编写自定义序列化和反序列化代码来保存对象、类和函数

我应该使用哪一个?

  • 如果你想存储一些你知道你只会在 python 程序的上下文中使用的东西,使用pickle
  • 如果您需要保存默认不可序列化的数据(即对象),请使用pickle
  • 如果您需要与平台无关的解决方案,请使用json
  • 如果您需要能够直接检查和编辑数据,请使用json

json的常见用例:

  • 配置文件(例如,node.js 使用package.json 文件来跟踪项目详细信息、依赖项、脚本等...)
  • 大多数REST API 使用json 来传输和接收数据
  • 需要嵌套列表/字典结构或需要可变长度列表/字典的数据
  • 可以替代csvxmlyaml 文件

【讨论】:

    【解决方案4】:

    如果你不想使用pickle,你可以将列表存储为文本,然后评估它:

    data = [0,1,2,3,4,5]
    with open("test.txt", "w") as file:
        file.write(str(data))
    
    with open("test.txt", "r") as file:
        data2 = eval(file.readline())
    
    # Let's see if data and types are same.
    print(data, type(data), type(data[0]))
    print(data2, type(data2), type(data2[0]))
    

    [0, 1, 2, 3, 4, 5] 类 'list' 类 'int'

    [0, 1, 2, 3, 4, 5] 类 'list' 类 'int'

    【讨论】:

    • 虽然这是一个选项,但这是一个非常糟糕的选项。 You should avoid eval。这正是python中json模块的用途。
    • 投反对票; eval 在这种情况下太危险了。任何可以编辑文件的恶意软件或黑客(或应用用户)都可以插入恶意代码,并且您的程序最终将运行他们放入其中的任何代码,因为正在读取的“值”被评估。
    【解决方案5】:

    如果您愿意,可以使用 numpy 的保存功能将列表保存为文件。 假设你有两个列表

    sampleList1=['z','x','a','b']
    sampleList2=[[1,2],[4,5]]
    

    这是将列表保存为文件的功能,记住你需要保留扩展名.npy

    def saveList(myList,filename):
        # the filename should mention the extension 'npy'
        np.save(filename,myList)
        print("Saved successfully!")
    

    这是将文件加载到列表中的函数

    def loadList(filename):
        # the filename should mention the extension 'npy'
        tempNumpyArray=np.load(filename)
        return tempNumpyArray.tolist()
    

    一个工作示例

    >>> saveList(sampleList1,'sampleList1.npy')
    >>> Saved successfully!
    >>> saveList(sampleList2,'sampleList2.npy')
    >>> Saved successfully!
    
    # loading the list now 
    >>> loadedList1=loadList('sampleList1.npy')
    >>> loadedList2=loadList('sampleList2.npy')
    
    >>> loadedList1==sampleList1
    >>> True
    
    >>> print(loadedList1,sampleList1)
    
    >>> ['z', 'x', 'a', 'b'] ['z', 'x', 'a', 'b']
    

    【讨论】:

      【解决方案6】:

      pickle 和其他序列化包工作。将其写入.py 文件也是如此,然后您可以将其导入。

      >>> score = [1,2,3,4,5]
      >>> 
      >>> with open('file.py', 'w') as f:
      ...   f.write('score = %s' % score)
      ... 
      >>> from file import score as my_list
      >>> print(my_list)
      [1, 2, 3, 4, 5]
      

      【讨论】:

      • 这不是一个好的解决方案。明确区分数据和代码;不要将数据存储为作为代码。
      • @Rawing:就个人而言,我更喜欢使用酸洗或其他方法......但是,SO 询问如何做到这一点,这是一种有效的方法。如果您查看接受的答案,将列表保存为字符串仅在某些情况下有效(其中有简单的条目,如1,2,3)。我还希望我的回复提供最快的方法。同样,我会在不需要速度时使用酸洗,而在需要速度时使用原始列表对象。使用import 读取数据存在一些危险,但如果需要,可以处理这些情况。所以我们可以同意不同意。
      • 我最近看到有人使用“导入”来保存小数据。我从来没有想过。我认为这可能是我的一个项目中的一种巧妙方法。如果其他人决定尝试使用这种方法,并且如果内存是一个问题,import sys; import mylist; del mylist, sys.modules['mylist']。不过,我还没有在实践中尝试过——只是测试了一下。今晚我会在实践中测试它。
      • @OldWinterton:你可能想看看这个:github.com/uqfoundation/klepto/blob/master/klepto/…
      【解决方案7】:

      我不喜欢很多答案的是,它通过每行写入文件行来产生过多的系统调用。恕我直言,最好使用 '\n' (行返回)加入列表,然后只将其写入文件一次:

      mylist = ["abc", "def", "ghi"]
      myfile = "file.txt"
      with open(myfile, 'w') as f:
          f.write("\n".join(mylist))
      

      然后打开它并再次获取您的列表:

      with open(myfile, 'r') as f:
          mystring = f.read()
      my_list = mystring.split("\n")
      

      【讨论】:

        【解决方案8】:

        我正在使用熊猫。

        import pandas as pd
        x = pd.Series([1,2,3,4,5])
        x.to_excel('temp.xlsx')
        y = list(pd.read_excel('temp.xlsx')[0])
        print(y)
        

        如果您要导入 pandas 进行其他计算,请使用此选项。

        【讨论】:

        • 您建议使用 excel 作为中间格式,听起来像是开销,并且总是遇到 xls 格式的格式问题。
        【解决方案9】:
        errorlist = ['aaaa', 'bbbb', 'cccc', 'dddd']
        
        f = open("filee.txt", "w")
        f.writelines(nthstring + '\n' for nthstring in errorlist)
        
        f = open("filee.txt", "r")
        cont = f.read()
        contentlist = cont.split()
        print(contentlist)
        

        【讨论】:

          【解决方案10】:

          我遇到了类似的问题,我需要读取保存为文本文件的列表。该列表有多个层,因此使用拆分将无济于事。 例如:

          list1.txt
          [(1,2,3),['a','b'],'a1']
          

          所以我做了什么,我将 list.txt 更改为 list.py,然后从 python 文件导入列表。 例如:

             list1.py
             a = [(1,2,3),['a','b'],'a1']
          

          然后:

          from list1 import a
          print(a)
          

          【讨论】:

            猜你喜欢
            • 2018-01-17
            • 1970-01-01
            • 2023-04-05
            • 1970-01-01
            • 1970-01-01
            • 2017-06-06
            • 2021-06-03
            • 2021-06-29
            • 1970-01-01
            相关资源
            最近更新 更多