使用递归生成器会减少内存消耗吗?

时间:2018-11-17 17:52:49

标签: python performance function loops tuples

我有一个元组池,例如[(0,0,27,4)(36,0,16,5)(14,36,14,8)],[......

我将使用以下规则从元组池中生成元组,总结每个索引不得超过或等于限制超过1次。

元组的长度为4,每个对象的整数都是int。 假设我有一个限制元组(30,29,28,27)和元组池。 例如,从池中选择元组,每个池中选择一个元组,

pool = [[(5,5,8,9),...],[(10,5,16,3),....],[(12,5,8,15),.....]]
selected =((5,5,8,9), (10,5,16,3), (12,5,8,15))

summing up each index,
5+10<30, 15+12<30 exceeding(or same as) limit 30 for 0 time ok
5+5<29, 10+5<29 exceeding limit 29 for 0 time ok
8+16<28, 24+8>28 exceeding limit 28 for 1 time ok (<2times)
9+3<12, 12+15=27 same as limit27 for 1 time ok

因此将产生((5,5,8,9),(10,5,16,3),(12,5,8,15))。

但是([(5,5,18,9),(10,5,10,3),(12,5,8,13)),

的示例
5+10<30, 15+12<30 exceeding(or same as) limit 30 for 0 time ok
5+5<29, 10+5<29 exceeding limit 29 for 0 time ok
18+10=28, 18+8 >28 exceeding limit 28 for 2 time False
9+3<12, 12+13<27 exceeding limit27 for 0 time ok

不会产生。
如果使用itertools.product,则需要额外的循环来生成元组。但是,如果我尝试修改给定的代码,其代码大致等于“ itertools.product”,则

def product(*args):
    pools = [tuple(pool) for pool in args]
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]

一直花费最后一行的“结果”是因为我要制作6个元组,每个元组的长度为80。

所以我生成了递归生成器,

def underlimit_product(*args, limit = (30,30,30,30), ncount = (0,0,0,0), exceed = 2, start = (0,0,0,0)):
    # (5,0,0,0),(0,5,0,0),(0,0,5,0),(0,0,0,5)
    pools = [tuple(pool) for pool in args]
    if max(ncount) >= exceed:
        raise StopIteration
    if not pools:
        raise StopIteration
    if len(pools) == 1:
        for y in pools[0]:
            if any([a+b>=c and d for a,b,c,d in zip(y,start,limit,ncount)]):
                if ncount:
                    continue
                else:
                    yield (y,)
            else:
                yield (y,)
        raise StopIteration
    else:
        for x in pools[0]:
            for y in pools[1]:
                count = [e+1 if b+c>=d else e for b,c,d,e in zip(x,start,limit,ncount)]
                if any(count):
                    n = underlimit_product(*pools[1:], ncount = count, exceed = exceed,limit = limit, start = [a+b for a,b in zip(x,start)])
                    for results in n:
                        yield (x,*results)
                else:
                    n = underlimit_product(*pools[1:], ncount = count, exceed = exceed,limit = limit, start = [a+b for a,b in zip(x,start)])
                    for results in n:
                        yield (x,*results)
    raise StopIteration

测试

pool = [[(5,5,8,9),(5,5,18,9)],[(10,5,16,3),(10,5,10,3)],[(12,5,8,15),(12,5,8,13)]]
b= list(underlimit_product(*pool, limit = (30,29,28,27)))
((5,5,8,9), (10,5,16,3), (12,5,8,15)) in b
True
((5,5,18,9), (10,5,10,3), (12,5,8,13)) in b
False
len(b)
16

因此,我看到了更好的产品……也许……,这会松开计算机的内存吗? 它会比使用itertools.product并检查所有值快得多吗?

0 个答案:

没有答案