如何将列表保存到文件并将其作为列表类型读取?

Oce*_*nce 27 python file list pickle python-3.x

假设我有列表得分= [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)
Run Code Online (Sandbox Code Playgroud)

但这会导致列表中的元素不是整数.

Viv*_*ble 52

您可以使用pickle 模块.这个模块有两种方法,

  1. Pickling(转储):将Python对象转换为字符串表示形式.
  2. 取消(加载):从存储的字符串表示中检索原始对象.

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

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

  • 酸洗可能是不安全的。请参阅 https://www.synopsys.com/blogs/software-security/python-pickling/ (3认同)

Jay*_*ody 28

尽管接受的答案有效,但您确实应该使用 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)
Run Code Online (Sandbox Code Playgroud)

优点

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

缺点

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

我应该使用哪一种?

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

的常见用例json

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


Oce*_*nce 18

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

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:
  for line in f:
    score.append(int(line.strip()))
Run Code Online (Sandbox Code Playgroud)

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

  • @Hadij他们希望能够在文本编辑器中打开它 (6认同)
  • 为什么你认为使用泡菜并不比你的建议更容易? (2认同)

小智 13

如果您不想使用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]))
Run Code Online (Sandbox Code Playgroud)

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

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

  • 虽然这是一个选择,但这是一个非常糟糕的选择。[你应该避免`eval`](/sf/ask/128305831/)。这正是 python 中“json”模块的用途。 (3认同)
  • 投反对票;在这种情况下 eval 太危险了。任何可以编辑该文件的恶意软件或黑客(或应用程序用户)都可以插入恶意代码,并且您的程序最终将运行他们在其中放入的任何代码,因为正在读取的“值”被评估。 (3认同)

小智 8

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

sampleList1=['z','x','a','b']
sampleList2=[[1,2],[4,5]]
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

一个工作示例

>>> 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']
Run Code Online (Sandbox Code Playgroud)


Mik*_*rns 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]
Run Code Online (Sandbox Code Playgroud)

  • @Rawing:就个人而言,我更喜欢使用酸洗或其他方法……但是,SO 询问如何做到这一点,这是一种有效的方法。如果您查看已接受的答案,则将列表保存为字符串仅在某些情况下有效(其中有像“1,2,3”这样的简单条目)。我还希望我的回复提供最快的方法。同样,我会在不需要速度时使用酸洗,而在需要速度时使用原始列表对象。使用 `import` 读取数据有一些危险,但如果需要,可以处理这些情况。所以我们可以同意不同意。 (2认同)

Ant*_*REL 5

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

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

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

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