【问题标题】:How to convert complex lists into strings and back in Python 3.7?如何在 Python 3.7 中将复杂列表转换为字符串并返回?
【发布时间】:2019-02-19 13:52:47
【问题描述】:

我正在尝试将 Python 列表保存到一个文件中,并在我重新启动程序时再次读取它们。问题是我的列表很复杂:即元组中有不同数量的元组。

我能想到的最好办法是最初将我的列表变成一个字符串(这可行),但我想不出任何办法来恢复更改。

with open(filename, 'w') as f:
            f.write(str(objs))
            f.close()

这可行,但我如何将其返回到列表中?

为了澄清我对复杂列表的定义,这里有一个例子:

[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 
0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), 
(1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 
2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 
0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

【问题讨论】:

  • 您可以将列表保存在pickle 文件中,或将其保存为json(尽管这会将元组转换为列表)。
  • “我能想到的最好的办法就是最初将我的列表变成一个字符串”不要那样做。使用受支持的序列化格式,例如 pickle 用于任意对象,或者即使只是 json 也可以用于简单列表

标签: python python-3.x python-3.7


【解决方案1】:

正如@snakecharmerb 已经提到的,您可以使用jsonpickle。这是一个例子:

代码:

my_list = [(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 
0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), 
(1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 
2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 
0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

import json

with open('my_list.json', 'w') as f:
    json.dump(my_list, f)

with open('my_list.json','r') as f:
    loaded_list = json.load(f)

print('Using json:')
print(loaded_list)

import pickle

with open('my_list.pkl', 'wb') as f:
    pickle.dump(my_list, f)

with open('my_list.pkl', 'rb') as f:
    loaded_list = pickle.load(f)

print('Using pickle:')
print(loaded_list)

输出:

Using json:
[[[[0.0, 0.0, 0.0], [1000.0, 0.0, 0.0], [0.0, 2.0, 0.0], [1000.0, 2.0, 0.0], [0.0, 0.0, 1000.0], [1000.0, 0.0, 1000.0], [0.0, 2.0, 1000.0], [1000.0, 2.0, 1000.0]], [[0, 2, 3, 1], [4, 6, 7, 5], [1, 3, 7, 5], [4, 6, 2, 0], [2, 6, 7, 3], [4, 0, 1, 5]], [[255, 0, 0], [255, 128, 0], [255, 255, 0], [255, 255, 255], [0, 0, 255], [0, 255, 0]]]]

Using pickle:
[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

如您所见,json 将元组转换为列表。

【讨论】:

  • 是的,这是正确的。因此,与其最初将列表转换为字符串并写入文件,不如将其保存在 pickle 文件中。 fileName = "my_list" fileObject = open(fileName,'wb') pickle.dump(my_list,fileObject) fileObject.close()
  • 您可以使用 cpickle 代替 pickle,cpickle 经过优化并且比 pickle 快得多,尤其是在数据量很大的情况下。上面的代码可以改成“import cpickle as pickle”
【解决方案2】:

str 函数会将您的复杂列表/嵌套列表和元组转换为字符串 此外,eval 将任何字符串转换为实际代码 sn-p

但是,正如 Taras Savchyn 所提到的,eval 可能导致 SQL 注入等。所以改用ast.literal_eval

因此:

>>>import ast

>>> mylist = [(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

>>> mylist
[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

>>> mystring = str(mylist)

>>> print(mystring)
'[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]'

>>> type(mystring)
<class 'str'>

>>> print(ast.literal_eval(mystring))
[(((0.0, 0.0, 0.0), (1000.0, 0.0, 0.0), (0.0, 2.0, 0.0), (1000.0, 2.0, 0.0), (0.0, 0.0, 1000.0), (1000.0, 0.0, 1000.0), (0.0, 2.0, 1000.0), (1000.0, 2.0, 1000.0)), ((0, 2, 3, 1), (4, 6, 7, 5), (1, 3, 7, 5), (4, 6, 2, 0), (2, 6, 7, 3), (4, 0, 1, 5)), ((255, 0, 0), (255, 128, 0), (255, 255, 0), (255, 255, 255), (0, 0, 255), (0, 255, 0)))]

>>> type(ast.literal_eval(mystring))
<class 'list'>

希望这能解决您的问题。您可以评论答案以询问任何进一步的问题

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-21
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-25
相关资源
最近更新 更多