Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 向嵌套字典中的内部字典添加新元素_Python_Dictionary - Fatal编程技术网

Python 向嵌套字典中的内部字典添加新元素

Python 向嵌套字典中的内部字典添加新元素,python,dictionary,Python,Dictionary,我正在使用Python 3.6.4。我试图创建一个由多个进程共享的嵌套字典,并根据各种函数的结果向内部字典添加键值对 下面是我的代码示例 manager = Manager() scores = manager.dict() def add_scores(name, game): global scores if name not in scores: scores[name] = {} if game in scores[name]:

我正在使用Python 3.6.4。我试图创建一个由多个进程共享的嵌套字典,并根据各种函数的结果向内部字典添加键值对

下面是我的代码示例

manager = Manager()
scores = manager.dict()

def add_scores(name, game):
    global scores
    if name not in scores:
        scores[name] = {}
    if game in scores[name]:
        scores[name][game] += 1
    else:
        scores[name] = {game: 1}
填充字典的外观示例如下

scores = { 'John': {'golf': '1', 'football': '2'}, 
           'Alice': {'basketball': '1', 'football': '3', 'tennis': 2}}
各种游戏都有功能,根据这些功能的结果,将为每个人创建一个键值对

我知道分数线[name]={game:1}是有问题的,因为它只是用上一个游戏覆盖了分数[name]字典

我也试过下面的代码

manager = Manager()
scores = manager.dict()

def add_scores(name, game):
    global scores
    if name not in scores:
        scores[name] = {}
    try:
        scores[name][game] += 1
    except Exception as e:
        print(e)
在这种情况下,printe给了我游戏的值。如果我只是为了测试而使用scores[name][game]=1,则没有错误,但字典是空的,例如{'John':{},'Alice':{}。我似乎不能简单地通过给这个键赋值来给字典添加新的键


如何添加到字典中?

您的内部记录也需要是manager.dict,因为它们也需要共享。这应该行得通

def add_scores(name, game):
    global scores
    if name not in scores:
        scores[name] = manager.dict()

    scores[name][game] = scores[name].get(game, 0) + 1
我还使用了.getgame,0来获取game的值,默认值为零,以消除try-catch和if块

记住,一旦完成,您将需要解压缩内部嵌套的dict,因为它们将是DictProxy对象

此示例适用于英特尔在Mac上发布的Python 3.6.3:

from multiprocessing import Process, Manager
import copy

manager = Manager()
scores = manager.dict()

def add_scores(name, game):
    global scores
    if name not in scores:
        scores[name] = manager.dict()

    scores[name][game] = scores[name].get(game, 0) + 1

players = {
    "Alex": ["Soccer", "Soccer", "Tennis"], 
    "Bob": ["Tennis", "Quidditch", "Soccer", "Tennis"]
    }

for iplayer, games in players.items():
    for igame in games:
        p = Process(target=add_scores, args=(iplayer, igame))
        p.start()
        p.join()


d = copy.deepcopy(scores)
for key, val in d.items():
    d[key] = copy.deepcopy(val)

print(d)
给出输出:

{
  'Alex': {'Soccer': 2, 'Tennis': 1}, 
  'Bob': {'Tennis': 2, 'Quidditch': 1, 'Soccer': 1}
}

你的内心格言也需要是manager.dict,因为它们也需要被分享。这应该行得通

def add_scores(name, game):
    global scores
    if name not in scores:
        scores[name] = manager.dict()

    scores[name][game] = scores[name].get(game, 0) + 1
我还使用了.getgame,0来获取game的值,默认值为零,以消除try-catch和if块

记住,一旦完成,您将需要解压缩内部嵌套的dict,因为它们将是DictProxy对象

此示例适用于英特尔在Mac上发布的Python 3.6.3:

from multiprocessing import Process, Manager
import copy

manager = Manager()
scores = manager.dict()

def add_scores(name, game):
    global scores
    if name not in scores:
        scores[name] = manager.dict()

    scores[name][game] = scores[name].get(game, 0) + 1

players = {
    "Alex": ["Soccer", "Soccer", "Tennis"], 
    "Bob": ["Tennis", "Quidditch", "Soccer", "Tennis"]
    }

for iplayer, games in players.items():
    for igame in games:
        p = Process(target=add_scores, args=(iplayer, igame))
        p.start()
        p.join()


d = copy.deepcopy(scores)
for key, val in d.items():
    d[key] = copy.deepcopy(val)

print(d)
给出输出:

{
  'Alex': {'Soccer': 2, 'Tennis': 1}, 
  'Bob': {'Tennis': 2, 'Quidditch': 1, 'Soccer': 1}
}

关键是要记住Manager.dict仅在setitem期间同步。如果直接编辑值对象,Manager.dict将看不到更改,因此不会同步。因为从Manager.dict的角度来看,键仍然指向同一个值对象;Manager.dict不监视pointed value对象内部的更改

下面是一个在Python 3.9和Python 3.6中运行的版本,以及介于两者之间的每个Python版本:

从多处理导入进程,管理器 def添加分数分数、姓名、游戏: 首先得到内心的格言 不需要使用.setdefault,因为我们将 无论如何,稍后覆盖该值 nmgm=_scores.getname,{} 修改它 nmgm[game]=nmgm.getgame,0+1 将其写回以便Manager.dict将同步 _分数[名称]=nmgm 玩家={ 亚历克斯:[足球,足球,网球], 鲍勃:[网球,魁地奇,足球,网球] } 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 经理 分数=manager.dict 对于iplayer,玩家中的游戏。项目: 对于游戏中的igame: p=Processtarget=add_分数,args=scores,iplayer,igame p、 开始 p、 加入 印刷分数 请注意,我没有使用全局,而是将Manager.dict实例传递给工作进程。在我的Python安装中,初始化管理器和_main______结构之外的分数导致运行时错误

结果:

{'Alex':{'Soccer':2,'Tennis':1},'Bob':{'Tennis':2,'Quiditch':1,'Soccer':1}
关键是要记住Manager.dict仅在setitem期间同步。如果直接编辑值对象,Manager.dict将看不到更改,因此不会同步。因为从Manager.dict的角度来看,键仍然指向同一个值对象;Manager.dict不监视pointed value对象内部的更改

下面是一个在Python 3.9和Python 3.6中运行的版本,以及介于两者之间的每个Python版本:

从多处理导入进程,管理器 def添加分数分数、姓名、游戏: 首先得到内心的格言 不需要使用.setdefault,因为我们将 无论如何,稍后覆盖该值 nmgm=_scores.getname,{} 修改它 nmgm[game]=nmgm.getgame,0+1 将其写回以便Manager.dict将同步 _分数[名称]=nmgm 玩家={ 亚历克斯:[足球,足球,网球], 鲍勃:[网球,魁地奇,足球,网球] } 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': 经理 分数=manager.dict 对于iplayer,玩家中的游戏。项目: 对于游戏中的igame: p=Processtarget=add_分数,args=scores,iplayer,igame p、 开始 p、 加入 印刷分数 请注意,我没有使用全局,而是将Manager.dict实例传递给工作进程。在我的Python安装中,初始化管理器和_main______结构之外的分数导致运行时错误

结果:

{'Alex':{'Soccer':2,'Tennis':1},'Bob':{'Tennis':2,'Quiditch':1,'Soccer':1}
可以使用defaultdict吗?可以使用defaultdict吗?这在Python 3.9中不起作用:有一个
r调用在_main__块之外。实际上,它在Python3.6中也不起作用:D。。。同样的RuntimeError也出现了。奇怪的是,我能够在Python3.6中运行它,并且输出是我所期望的。我会接受这个答案,因为这是我尝试过的答案。@pepoluan,这是一个很好的观点。我不确定我正在运行的哪个版本从我的家用计算机上回答了这个问题,但我会在可能的情况下将其添加到我的答案中。@Rayne你应该不接受我的答案,而接受pepoluan的答案,因为这是一个更好的答案,而且更普遍适用。这在Python 3.9中不起作用:在u main_u_u块之外有一个管理器调用。实际上,它在Python3.6中也不起作用:D。。。同样的RuntimeError也出现了。奇怪的是,我能够在Python3.6中运行它,并且输出是我所期望的。我会接受这个答案,因为这是我尝试过的答案。@pepoluan,这是一个很好的观点。我不确定我正在运行的哪个版本从我的家用计算机上回答了这个问题,但我会在可能的情况下将其添加到我的答案中。@Rayne你应该不接受我的答案,而接受pepoluan的答案,因为这是一个更好的答案,更普遍适用。谢谢你的解决方案。很抱歉,我无法接受此解决方案,因为我已经尝试了@Pranav Hosangadi提供的解决方案。如果我能接受两个答案,我会的。@Rayne,没关系。只想分享一下Manager.dict的gotcha w.r.t用法,希望您能制作出出色的多处理程序!:-我刚刚尝试过这个解决方案,它对我也很有效。事实上,我想我更喜欢它,因为最后不需要做深度拷贝。所以我会接受这个答案。谢谢谢谢你的解决方案。很抱歉,我无法接受此解决方案,因为我已经尝试了@Pranav Hosangadi提供的解决方案。如果我能接受两个答案,我会的。@Rayne,没关系。只想分享一下Manager.dict的gotcha w.r.t用法,希望您能制作出出色的多处理程序!:-我刚刚尝试过这个解决方案,它对我也很有效。事实上,我想我更喜欢它,因为最后不需要做深度拷贝。所以我会接受这个答案。谢谢