如何通过多次执行程序来持久保存列表数据?

时间:2014-08-15 00:39:23

标签: python list pickle execution persist

我的程序很简单。我循环访问用户输入并将其输入作为整数添加到列表中,直到用户中断循环。然后我编写了一些用于分析数据的代码。然而,下次我运行程序时,我添加到列表中的数据消失了。我知道一个与此问题差不多的问题,然而,我无法理解答案,因为我对python很新。我知道泡菜模块,但我不明白它的作用。如果使用泡菜是我最好的选择,请解释它是如何工作的。

2 个答案:

答案 0 :(得分:2)

如果您拥有的是一些像整数这样的简单类型的列表,那么pickle就太过分了。您可以将每个整数写入一行,如下所示:

with open('myfile.txt', 'w') as f:
    for value in values:
        f.write('{}\n'.format(value))

然后,请回读:

values = []
with open('myfile.txt') as f:
    for line in f:
        values.append(int(line))

显然,如果您尝试保存可能包含换行符的字符串,或者比仅调用int更难解析的更复杂的数据类型,这将无效。在这种情况下,您可能希望查看JSON,YAML或Pickle格式。

本教程有一篇关于Input and Output的精彩章节,涵盖了这一点,以及更多内容(虽然它假设您已经阅读了前面的章节,或者在其他地方获得了相同的信息,或者愿意回去阅读如果你感到困惑,你错过了什么。)

答案 1 :(得分:0)

pickle实际上非常简单。它将python对象转换为可以存储在文件中的唯一字符集合。这些角色实际上是一种迷你语言的“操作码”'告诉我们如何唯一地创建你的python对象。无论如何,在关闭解释器之前,您将列表保存到dump的文件中。

>>> l = range(100)  
>>> import pickle
>>> 
>>> f = open('bar.txt', 'w')
>>> pickle.dump(l, f)

然后当你再次启动python时,你使用load

Python 2.7.8 (default, Jul 13 2014, 02:29:54) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> f = open('bar.txt', 'r')
>>> import pickle
>>> l = pickle.load(f)
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

如果查看dumps,您可以看到pickle如何将整数列表转换为唯一字符。首先使用"天真" pickle协议,其次使用更加压缩的协议('-1',对于python 2.7是协议'2')。

>>> pickle.dumps(l)
'(lp0\nI0\naI1\naI2\naI3\naI4\naI5\naI6\naI7\naI8\naI9\naI10\naI11\naI12\naI13\naI14\naI15\naI16\naI17\naI18\naI19\naI20\naI21\naI22\naI23\naI24\naI25\naI26\naI27\naI28\naI29\naI30\naI31\naI32\naI33\naI34\naI35\naI36\naI37\naI38\naI39\naI40\naI41\naI42\naI43\naI44\naI45\naI46\naI47\naI48\naI49\naI50\naI51\naI52\naI53\naI54\naI55\naI56\naI57\naI58\naI59\naI60\naI61\naI62\naI63\naI64\naI65\naI66\naI67\naI68\naI69\naI70\naI71\naI72\naI73\naI74\naI75\naI76\naI77\naI78\naI79\naI80\naI81\naI82\naI83\naI84\naI85\naI86\naI87\naI88\naI89\naI90\naI91\naI92\naI93\naI94\naI95\naI96\naI97\naI98\naI99\na.'
>>> 
>>> pickle.dumps(l, -1)
'\x80\x02]q\x00(K\x00K\x01K\x02K\x03K\x04K\x05K\x06K\x07K\x08K\tK\nK\x0bK\x0cK\rK\x0eK\x0fK\x10K\x11K\x12K\x13K\x14K\x15K\x16K\x17K\x18K\x19K\x1aK\x1bK\x1cK\x1dK\x1eK\x1fK K!K"K#K$K%K&K\'K(K)K*K+K,K-K.K/K0K1K2K3K4K5K6K7K8K9K:K;K<K=K>K?K@KAKBKCKDKEKFKGKHKIKJKKKLKMKNKOKPKQKRKSKTKUKVKWKXKYKZK[K\\K]K^K_K`KaKbKce.'
>>> pickle.dumps([1,2,3], -1)
'\x80\x02]q\x00(K\x01K\x02K\x03e.'
>>> pickle.dumps([], -1)
'\x80\x02]q\x00.'
>>> pickle.dumps((1,2,3), -1)
'\x80\x02K\x01K\x02K\x03\x87q\x00.'
>>> pickle.dumps((), -1)
'\x80\x02).'

如果仔细查看最后几个,您可以看到始终以\x80\x02开头,它告诉我它是协议2,然后)表示元组,或者列表的] ... \x01K是整数1,依此类推。我不会尝试直接写这些字符串,除非你真的知道你在做什么......最好让pickle为你做。

您可以查看pickle.py本身的许多操作码列表:https://github.com/python/cpython/blob/master/Lib/pickle.py#L97