Python-在迭代另一个字典的同时向字典添加新条目

时间:2020-02-28 20:10:49

标签: python loops dictionary

我想检查一本字典中的点与另一本字典之间的点是否重叠。 如果没有重叠,则使用值在字典中创建一个新键。 实施以下代码时出现错误。

RuntimeError: dictionary changed size during iteration


for k1 in d1:
    for k2 in d2:
        if(overlap(k1,k2)==False):
            d2[len(d2)+1]=d1[k1]                

还有另一种实现方法吗?

编辑:

d1 = {"file1":[2,3],"file2":[11,15]}
d2 = {1:[1,5],2:[6,10]}

输出:

d2 = {1:[1,5],2:[6,10],3:[11,15]}

4 个答案:

答案 0 :(得分:2)

我相信您正在寻找dict.update()

d1 = {'foo': 0,
      'bar': 1}

d2 = {'foo': 0,
      'bar': 1,
      'baz': 2}

d1.update(d2)

结果是:

d1 = {'foo': 0,
      'bar': 1,
      'baz': 2}

编辑:

import itertools

d1 = {"file1":[2,3],
      "file2":[11,15]}

d2 = {1:[1,5],
      2:[6,10]}

d2 = {**d2, **{max(d2.keys())+i+1: v for i, (k, v) in enumerate({k: v for k, v in d1.items() if not any(i in range(v[0], v[1]+1) for i in itertools.chain.from_iterable(range(v[0], v[1]+1) for v in d2.values()))}.items())}}

产生:

d2 = {1: [1, 5],
      2: [6, 10],
      3: [11, 15]}

?

答案 1 :(得分:1)

如果您尝试合并字典,则更快的方法是使用其中之一

a = dict(one=1,two=2,three=3,four=4,five=5,six=6)
b = dict(one=1,two=2,three=5,six=6, seven=7, nine=9)
a.update(b)

哪个给{'one': 1, 'two': 2, 'three': 5, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'nine': 9}

或者您可以使用c = dict(a, **b)

答案 2 :(得分:0)

您在那里不需要双循环。循环浏览d1中的键。检查d2.keys是否包含k1。如果不是,请将k1添加到d2。我这里没有语法,但是沿这些方面有些意思。

for k1 in d1.keys:
    if not k1 in d2.keys:
        d2[k1] = d1[k1]

return d2

答案 3 :(得分:0)

根据您的描述,编辑和评论,听起来dict.update()不会给您想要的结果。

您遇到的错误是因为循环假设启动后将要迭代的项目数。在循环期间,您更改该数字,使假设无效,从而导致程序失败。

要解决此问题,您需要迭代这些项目的副本。您还提到您关心的是值而不是键,因此还需要调整要迭代的

现在,您实际上并没有发布overlap函数的功能,因此根据您的评论/示例,我假设这样的事情:

def overlap(left, right):
    return left[0] - right[-1] == 1

在大多数情况下,overlap的实际实现与问题无关,但是上面的代码至少给了我您期望的输出。

然后我将您的代码调整为以下内容:

for v1 in list(d1.values()):
    for v2 in list(d2.values()):
        # If v1 overlaps v2
        if overlap(v1, v2):
            # Add v1 to d2 under the next sequential key
            d2[len(d1) + 1] = v1

通过使用list(d1.values()),我不再需要在修改字典时对其本身进行迭代-而是在循环开始时对内容(此处特别是这些值)进行“快照”。

使用此数据和示例数据,循环后d2包含{1: [1, 5], 2: [6, 10], 3: [11, 15]}

相关问题