gpt4 book ai didi

python - 如何在 Python 中迭代字典代理?

转载 作者:太空狗 更新时间:2023-10-29 17:21:01 26 4
gpt4 key购买 nike

我正在使用 Python 的 multiprocessing.Manager 来共享对一个进程将生成的数据集的访问,而其他进程将查看该数据集。但是,我遇到了 manager.dict() 返回的字典代理不支持 iteritems() 的问题。

我可以遍历 items(),但这意味着要为字典中的所有项目构建一个新的元组,这是一个很大的数字。有没有一种方法可以在不构建中间列表/元组的情况下做到这一点,从而只使用恒定数量的额外内存?

注意:如果解决方案要求生成过程暂停以进行迭代,则可以。

最佳答案

您可以遍历 keys() 以减少内存占用。您必须防止 key 被删除。

否则,这里有一个示例,其中包含两种不同的方法,可让您遍历字典中的项目。本例中的iteritems() 方法只对创建管理器对象的进程和管理器对象创建的子进程有效。那是因为需要管理器对象来创建新的代理,而其他进程无权访问它。 iteritems2() 方法适用于其他进程,因为它不依赖于在这些进程中创建新代理。

import multiprocessing as mp
import multiprocessing.managers

class mydict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.iters = {}

def iteritems(self):
print "iteritems", mp.current_process()
return dict.iteritems(self)

def _iteritems_start(self):
print "_iteritems_start", mp.current_process()
i = dict.iteritems(self)
self.iters[id(i)] = i
return id(i)

def _iteritems_next(self, iter_id):
try:
return self.iters[iter_id].next()
except StopIteration:
del self.iters[iter_id]
return None

class mydict_proxy(mp.managers.DictProxy):
def iteritems(self):
print "iteritems proxy", mp.current_process()
return self._callmethod("iteritems")

def iteritems2(self):
print "iteritems2 proxy", mp.current_process()
iter_id = self._callmethod("_iteritems_start")
def generator():
while True:
a = self._callmethod("_iteritems_next",
(iter_id,))
if a == None:
return
yield a
return generator()

_method_to_typeid_ = { "iteritems": "Iterator" }
_exposed_ = mp.managers.DictProxy._exposed_
_exposed_ += ("iteritems", "_iteritems_start", "_iteritems_next")

class mymanager(mp.managers.BaseManager):
pass
mymanager.register("mydict", mydict, mydict_proxy)
mymanager.register("Iterator", proxytype = mp.managers.IteratorProxy,
create_method = False)

def other(d):
for k, v in d.iteritems2():
d[k] = v.lower()
for k, v in d.iteritems():
d[k] = ord(v)

def main():
manager = mymanager()
manager.start()
d = manager.mydict(list(enumerate("ABCDEFGHIJKLMNOP")))
for (k, v) in d.iteritems():
print k, v
proc = mp.Process(target = other, args = (d,))
proc.start()
proc.join()
for (k, v) in d.iteritems():
print k, v

if __name__ == "__main__":
main()

请注意,虽然这段代码可能更有效地利用内存,但它可能会慢很多。

关于python - 如何在 Python 中迭代字典代理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19568232/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com