我想检查一本字典中的点与另一本字典之间的点是否重叠。 如果没有重叠,则使用值在字典中创建一个新键。 实施以下代码时出现错误。
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]}
答案 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]}
。