如何解决允许对突变进行迭代的python生成器功能
我想定义一个生成器函数,该函数可以迭代正在变异的字典对象。
def generator(d):
for k,v in sorted(d.items()):
yield (k,v)
d = {1:'a',2:'x',4:'m',8:'d',16:'f'}
i = generator(d)
print(next(i))
print(next(i))
del d[8]
print(next(i))
d[16] = "f"
d[32] = "z"
print(next(i))
print(next(i))
如果我执行上面的代码,我将得到:
(1,'a')
(2,'x')
(4,'m')
(8,'d')
(16,'f')
所需的输出应为:
(1,'m')
(16,'f')
(32,'z')
我不了解的部分是当我将d = {1:'a',16:'f'}
分配给i = generator(d)
时,该字典已经添加到功能generator(d)
中,并成为具有初始字典的生成器实例。因此,每当我使用del
函数时,生成器都将d = {1:'a',16:'f'}
作为其参数保持不变。我将如何实现这一目标?
解决方法
您需要处理异常情况以检查何时更改了字典,并需要使用缓冲区来保持键已经产生。
def generator(d):
buffer = set()
while True:
old_hash = hash(frozenset(d.items()))
try:
for k,v in d.items():
if hash(frozenset(d.items())) != old_hash:
raise RuntimeError('dictionary changed size during iteration')
if (k,v) not in buffer:
buffer.add((k,v))
yield k,v
break
except RuntimeError as e:
if str(e) != 'dictionary changed size during iteration':
raise e
修改字典后,异常会导致for循环重新启动,跳过已经产生的键值对,外循环会在更改字典时重新启动所有内容,并在d中的每个元素产生后中断。
您唯一需要了解的是,当每一项都返回并且生成器停止时,对字典的更改不会像现在的代码那样重新启动它
EDIT添加了哈希,以捕获注释中提到的非常具体的情况
,您需要按索引而不是按元素来产生。您需要重新生成每个产量之间的列表以捕获变化。
def generator(d):
for i in range(len(d)):
dd = sorted(d.items())
if i < len(dd):
yield dd[i]
d = {1:'a',2:'x',4:'m',8:'d',16:'f'}
i = generator(d)
print(next(i))
print(next(i))
del d[8]
print(next(i))
d[16] = "f"
d[32] = "z"
print(next(i))
print(next(i))
输出
(1,'a')
(2,'x')
(4,'m')
(16,'f')
(32,'z')
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。