加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 复制生成器而不会炸毁内存

发布时间:2020-12-20 13:09:41 所属栏目:Python 来源:网络整理
导读:我正在写一个 python类,它找到所有可能的 magic squares给定一个整数大小和一个生成器用于可能的组合.这些组合是长度为** 2的元组,并被分成大
我正在写一个 python类,它找到所有可能的 magic squares给定一个整数大小和一个生成器用于可能的组合.这些组合是长度为** 2的元组,并被分成大小×大小的网格.代码本身工作正常,但重用生成器似乎需要itertools.tee.在下面显示的示例中,这会导致线程使用的内存跳转到300MB,因为迭代器中的每个值都存储在列表中.

from itertools import permutations,tee

class MagicSquare:
    def __init__(self,size,combinations):
        self.size = size
        self.range = range(self.size)
        self.combinations = combinations

    def getGrid(self,entries):
        return [ entries[self.size*i:self.size*(i+1)] for i in self.range ]

    def checkGrid(self,grid):
        check_sum = sum(grid[0])
        if any( sum(row) != check_sum for row in grid ): 
            return False
        if any( sum(row[col] for row in grid) != check_sum for col in self.range ): 
            return False
        if sum(grid[diag][diag] for diag in self.range) != check_sum: 
            return False
        if sum(grid[diag][self.size-diag-1] for diag in self.range) != check_sum: 
            return False
        return True

    def solutions(self):
        combinations,self.combinations = tee(self.combinations)
        for entries in combinations:
            grid = self.getGrid(entries)
            if self.checkGrid(grid):
                yield grid

if __name__ == '__main__':
    combs = permutations(range(20,30),9)
    ms = MagicSquare(3,combs)
    for solution in ms.solutions():
        for row in solution:
            print row
        print

想到这个问题有两个明显的解决方案.首先,我可以要求提供生成器而不是请求生成器本身的函数,但这需要用户包装它们的生成器表达式.其次,我可以缓存解决方案.为了论证,假设我不再需要检查对角线是否有足够数量的解决方案,所以我需要更新checkGrid并重复组合.

所以,我的问题是:在没有创建这个潜在的巨大内存问题的情况下,真的没有办法复制生成器吗?我不关心保留生成器的部分状态,我只是想让它迭代与原始生成器相同的值.

编辑

看起来在Python 3.X中,您可以使用copy.deepcopy来复制依赖项都可以选择的itertools对象.

解决方法

没有什么是不可能的…

以下情况适用于itertools.permutations.不要以为它适用于任何迭代,因为它不会!

>>> from itertools import permutations
>>> combs = permutations(range(20,9)
>>> from copy import deepcopy
>>> combs2 = deepcopy(combs)
>>> next(combs)
(20,21,22,23,24,25,26,27,28)
>>> next(combs2)
(20,28)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读