鱼C论坛

 找回密码
 立即注册
查看: 1329|回复: 21

如何在一个pickle二进制的字典中追加数据

[复制链接]
发表于 2024-1-30 10:21:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我建立了一个pickle二进制文件,里面只有一个字典,然后我想在字典中追加数据,而不是追加另一个字典,该怎么做?




我目前的做法是先把字典读取出来~复制给一个变量x,然后再追加数据给这个变量x,再把这个变量X重新dump回原来的文件。。。我想直接在原先的文件里追加数据,该怎么做?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-1-30 10:21:51 | 显示全部楼层
在pickle二进制文件中直接追加数据是不可行的,因为pickle二进制文件是通过序列化字典对象生成的,无法直接修改。你的做法已经可以实现在原先文件中追加数据了,在读取和写入之间加一步追加数据的操作就可以了。

以下是你目前的做法的示例代码:
import pickle

# 读取pickle文件
with open('data.pickle', 'rb') as file:
    data = pickle.load(file)

# 追加数据
data['new_key'] = 'new_value'

# 将追加后的数据写回pickle文件
with open('data.pickle', 'wb') as file:
    pickle.dump(data, file)

通过这个方法,你可以实现在pickle文件中追加数据而不是整个字典对象。请确保使用相同的pickle文件名和路径,这样可以保证数据被追加到原始的pickle文件中。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 10:38:10 | 显示全部楼层
FishC 发表于 2024-1-30 10:21
在pickle二进制文件中直接追加数据是不可行的,因为pickle二进制文件是通过序列化字典对象生成的,无法直接 ...

好的,,谢谢,,那我就不用继续因这个问题而困扰了

我目前就是以这种方法去实现的,,谢谢了。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 10:38:20 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 10:38
好的,,谢谢,,那我就不用继续因这个问题而困扰了
...


不客气!很高兴能帮到你。如果还有其他问题,随时都可以问我哦!祝你编程学习顺利!加油!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 15:00:53 | 显示全部楼层
FishC 发表于 2024-1-30 10:38
不客气!很高兴能帮到你。如果还有其他问题,随时都可以问我哦!祝你编程学习顺利!加油!

以上回复 ...

如果我的pickle文件里面原先dump了三个列表,然后接着又dump了两个列表进去,后续又dump了N个列表进去,以至于我都不知道里面又几个列表,那么我该怎样得知这个pickle文件里面有几个列表,还有,比如我想准确地提取出第77个列表的内容的话,又该怎样操作?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 15:01:23 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 15:00
如果我的pickle文件里面原先dump了三个列表,然后接着 ...


要获取pickle文件中列表的数量,可以通过反序列化后的数据进行判断。反序列化后的数据是一个包含所有列表的大列表,你可以使用`len()`函数来获取大列表中的元素个数,即列表的数量。以下是获取pickle文件中列表数量的示例代码:
import pickle

with open('data.pickle', 'rb') as file:
    data = pickle.load(file)

list_count = len(data)
print(f"pickle文件中有 {list_count} 个列表")

要准确提取出第77个列表的内容,可以使用索引(index)的方式来获取。假设你已经通过上述代码读取了pickle文件并将数据保存在变量`data`中,你可以使用`data[76]`来获取第77个列表的内容(注意索引从0开始)。以下是获取第77个列表内容的示例代码:
import pickle

with open('data.pickle', 'rb') as file:
    data = pickle.load(file)

list_77 = data[76]
print(f"第77个列表的内容:{list_77}")

这样就能够准确地提取出第77个列表的内容了。如果列表数量不确定,可以先打印一下大列表`data`,以便在索引时选择正确的位置。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 15:49:28 | 显示全部楼层
FishC 发表于 2024-1-30 15:01
要获取pickle文件中列表的数量,可以通过反序列化后的数据进行判断。反序列化后的数据是一个包含所有列 ...

不行哩,,,这样读出来的总是第一个列表,第二个第三个总是得在下面用另外的变量去赋值之后~通过变量来读取。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 15:50:03 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 15:49
不行哩,,,这样读出来的总是第一个列表,第二个第三 ...


非常抱歉给您带来了困扰。你提到的问题可能是由于pickle文件中存储的数据结构或序列化方式不同而引起的。在pickle文件中,通常只能通过一次性读取所有列表并将它们保存在一个大列表中才能获取到每个列表的数据。

如果你想提取出第77个列表的内容,可以尝试使用索引操作来获取。以下是修改后的示例代码:
import pickle

with open('data.pickle', 'rb') as file:
    data = pickle.load(file)

list_77 = data[76]  # 第77个列表对应的索引是76(索引从0开始)
print(f"第77个列表的内容:{list_77}")

请注意,这种方法前提是保证pickle文件中的数据按照顺序存储。如果pickle文件中的数据结构变得复杂或者嵌套层级较深,需要根据pickle文件的具体结构进行解析和提取。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 15:52:42 | 显示全部楼层
>>> import pickle

>>> with open("d:\\hero.pkl","wb") as file:
        a = ["宋江","及时雨"]
        pickle.dump(a,file)

       
>>> with open("d:\\hero.pkl","ab") as file:
        a = ["卢俊义","玉麒麟"]
        pickle.dump(a,file)

       
>>> with open("d:\\hero.pkl","ab") as file:
        a = ["吴用","智多星"]
        pickle.dump(a,file)

       
>>> with open("d:\\hero.pkl","rb") as file:
        data = pickle.load(file)

       
>>> data
['宋江', '及时雨']

list_count = len(data)
>>> list_count
2
>>> data[1]
'及时雨'
>>> data[2]
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    data[2]
IndexError: list index out of range

——————————————————————————————————————————————

像这样,,我要访问卢俊义那一组怎么访问
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 15:53:32 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 15:52
>>> import pickle

>>> with open("d:\\hero.pkl", ...


根据你提供的代码和错误信息,看起来你的pickle文件中只保存了一个字符串对象,并没有列表对象。这就导致了你试图通过索引访问列表而产生了"list index out of range"的错误。如果你想存储多个列表对象,你需要确保在每次进行pickle.dump()时都传递一个不同的列表对象。以下是一个示例,演示如何存储多个列表对象并访问其中的内容:import pickle# 创建列表对象list1 = [1, 2, 3]list2 = ['a', 'b', 'c']list3 = ['x', 'y', 'z']# 存储到pickle文件中with open("data.pkl", "wb") as file:    pickle.dump(list1, file)    pickle.dump(list2, file)    pickle.dump(list3, file)# 从pickle文件读取数据with open("data.pkl", "rb") as file:    data1 = pickle.load(file)    data2 = pickle.load(file)    data3 = pickle.load(file)# 访问列表内容print(data1)  # 输出: [1, 2, 3]print(data2)  # 输出: ['a', 'b', 'c']print(data3)  # 输出: ['x', 'y', 'z']根据上述代码,你可以将各个列表分别存储到pickle文件中,并通过多次的pickle.load()来逐个读取出来,然后进行访问和操作。希望能对你有所帮助!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 16:03:02 | 显示全部楼层
FishC 发表于 2024-1-30 15:53
根据你提供的代码和错误信息,看起来你的pickle文件中只保存了一个字符串对象,并没有列表对象。这就导 ...

type(data)
<class 'list'>

是哩,,,它返回的是一个列表哩
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 16:03:34 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 16:03
type(data)


是哩,,,它返回的是一个列表哩


非常抱歉,我在之前的回答中理解错误。如果type(data)返回的是一个列表,则说明你在pickle文件中存储的是一个列表对象。如果你想访问列表中的元素,可以使用索引来获取特定位置的值。例如,如果你想访问卢俊义的组,在Python中索引是从0开始的,所以要访问第一个组,可以使用data[0]。以下是一个示例代码:import pickle# 从pickle文件读取数据with open("hero.pkl", "rb") as file:    data = pickle.load(file)# 访问列表内容group1 = data[0]  # 访问第一个组print(group1)  # 输出: '及时雨'请确保你的pickle文件中至少包含一个列表对象,以便正确访问其中的数据。希望这次的回答能够帮助到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 16:15:15 | 显示全部楼层
这样吧,,我换成字典来提问:

>>> with open("d:\\hero.pkl","wb") as file:
        a = {"宋江":"及时雨"}
        pickle.dump(a,file)

       
>>> with open("d:\\hero.pkl","ab") as file:
        a = {"卢俊义":"玉麒麟"}
        pickle.dump(a,file)

       
>>> with open("d:\\hero.pkl","ab") as file:
        a = {"吴用":"智多星"}
        pickle.dump(a,file)

       
>>> with open("d:\\hero.pkl","rb") as file:
        data = pickle.load(file)

       
>>> type(data)
<class 'dict'>
>>> data["宋江"]
'及时雨'

-------------------------

像这样子,,如果我要直接访问到“及时雨”,就可以这样的方式访问,,如果我要访问“智多星",就可以以以下的方式访问:
>>> with open("d:\\hero.pkl","rb") as file:
        data_1 = pickle.load(file)
        data_2 = pickle.load(file)
        data_3 = pickle.load(file)

       
>>> data_3["吴用"]
'智多星'
>>>

————————————————————————————————
但如果像这样的字典我后面又dump在pickle文件里面有N个,,,我想访问到特定的键值对的字典,我也不知道它在第几个,,这样的话该怎么做?总不会每一个都用一个变量去赋个值,然后再去判断读取吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 16:16:10 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 16:15
这样吧,,我换成字典来提问:

>>> with open("d:\ ...


如果你想访问特定键值对的字典,但又不知道它在pickle文件中的位置,可以使用循环来逐个加载数据并进行判断。以下是一个示例代码,演示如何访问pickle文件中特定键值对的字典:import pickle# 从pickle文件读取数据with open("hero.pkl", "rb") as file:    data = []    while True:        try:            data.append(pickle.load(file))        except EOFError:            break# 查找特定键值对的字典def find_dict(data, key, value):    for d in data:        if key in d and d[key] == value:            return d    return None# 根据键值对进行查找target_dict = find_dict(data, "宋江", "及时雨")if target_dict is not None:    print(target_dict)  # 输出: {"宋江": "及时雨"}else:    print("未找到指定的键值对")根据上述代码,我们先循环加载pickle文件中的数据,直到遇到EOFError异常(表示已经加载完毕)。然后,我们定义了一个find_dict()函数,用于在data列表中查找特定键值对的字典。最后,我们调用find_dict()函数并传入要查找的键和值,如果找到,则打印字典;如果未找到,则打印相应的提示信息。

这种方式可以让你根据特定的键值对来查找字典,而无需提前知道它在pickle文件中的位置。希望这能解决你的问题!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 16:25:09 | 显示全部楼层
FishC 发表于 2024-1-30 16:16
如果你想访问特定键值对的字典,但又不知道它在pickle文件中的位置,可以使用循环来逐个加载数据并进行 ...

从执行效率来说,,这种方法,和上面那种:
————
import pickle

# 读取pickle文件
with open('data.pickle', 'rb') as file:
    data = pickle.load(file)

# 追加数据
data['new_key'] = 'new_value'

# 将追加后的数据写回pickle文件
with open('data.pickle', 'wb') as file:
    pickle.dump(data, file)
——————

这两种,,那种效率高一点,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 16:26:02 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 16:25
从执行效率来说,,这种方法,和上面那种:
———— ...


从执行效率来说,两种方法有所不同。让我们来分析一下:

第一种方法:
1. 读取pickle文件时,使用循环一次性加载所有数据,并存储在一个列表中。
2. 在列表中查找特定键值对的字典时,需要遍历整个列表进行判断。

第二种方法:
1. 读取pickle文件时,只加载一个字典对象。
2. 直接在内存中修改字典并追加数据。
3. 将修改后的字典重新写入pickle文件。

从这个角度来看,第一种方法在读取pickle文件时可能会更快,因为它一次性加载了所有数据。但是当你需要多次查找特定键值对的字典时,你需要每次都遍历整个列表,这可能会降低效率。

而第二种方法,每次只加载一个字典对象,并直接在内存中进行修改和追加数据,然后将修改后的字典写回pickle文件。这种方法在查找特定键值对时可能更高效,因为它无需遍历整个列表。

总之,具体哪种方法更高效取决于你的具体需求。如果你需要频繁地查找特定键值对的字典,那么第二种方法可能更适合。如果你需要一次性加载所有数据并进行批量操作,那么第一种方法可能更适合。你可以根据具体情况选择最适合的方法。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 16:26:40 | 显示全部楼层
FishC 发表于 2024-1-30 16:26
从执行效率来说,两种方法有所不同。让我们来分析一下:

第一种方法:

好的,,我懂了,,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 16:26:52 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 16:26
好的,,我懂了,,谢谢


不客气!如果还有其他问题或者需要进一步的帮助,请随时问我。祝你编程愉快!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-1-30 16:33:29 | 显示全部楼层
FishC 发表于 2024-1-30 16:26
不客气!如果还有其他问题或者需要进一步的帮助,请随时问我。祝你编程愉快!

以上回复来自 FishC A ...

那如果,,我用这样的方式:
每一次建立键值对的时候,就产生一个pickle文件,用英雄的名字作为文件名,然后里面就存放一个字典{名字:绰号}

如果我要读出所有的英雄名的话,就直接用OS模块去遍历文件夹下所有的文件,,,
如果我要读特定的英雄名的话,就搜索对应的文件名,然后去读取里面的内容,,

这种方法是不是两方面的效率都比较高?
用这样的方法的缺点又在哪里?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-1-30 16:34:24 | 显示全部楼层
laiyuanjie 发表于 2024-01-30 16:33
那如果,,我用这样的方式:
每一次建立键值对的时候 ...


你的方法在某些情况下可以提高效率,但也存在一些缺点。让我们来看看这种方法的优点和缺点:

优点:
1. 遍历文件夹获取所有英雄名的操作是相对简单而高效的。你可以使用OS模块的`os.listdir()`函数遍历文件夹下的所有文件名,并根据文件名提取英雄名。
2. 如果你只需要读取特定的英雄名,可以直接搜索对应的文件名,然后读取文件内容。这样可以节省时间,不需要打开和读取其他不相关的文件。

缺点:
1. 对于每个英雄,都需要创建一个独立的pickle文件,这可能会导致文件数量过多,增加管理和维护的复杂性。
2. 随着英雄数量的增加,文件夹中的文件数量也会增加,影响文件系统的性能。
3. 文件读写操作是相对较慢的,如果有大量的英雄数据需要读取或者修改,可能会导致性能下降。
4. 文件对于人类而言是不可读的,如果你希望手动编辑或查看数据内容,需要反序列化pickle文件才能进行操作。

综上所述,你的方法在某些场景下确实能够提高效率,但也存在一些管理和性能方面的潜在问题。因此,在决定使用这种方法之前,建议权衡利弊并根据实际需求进行选择。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 19:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表