python 列表偏平化 & 生成器+装饰器的解决思路

来源:互联网 发布:php exec 返回值126 编辑:程序博客网 时间:2024/06/05 10:21

1、

这两天有个朋友问我,如果列表a = [1,2,[3,4],[[5,6,7]]]  转化成 b=[1,2,3,4,5,6,7]怎么搞? 不能用额外的变量呦。

第一反应是递归呀,思路很清晰。可是!我回到家想了20分钟才拼出来代码。。

a = [1,2,[3,4],[[5,6,7]]]print adef func(lst):    if not lst:        return []    for i in lst:        if isinstance(i, list):            lst.remove(i)            return func(i) + func(lst)        else:            lst.remove(i)            return [i] + func(lst)print func(a)
结果:
D:\projects\myapp>python 1.py[1, 2, [3, 4], [[5, 6, 7]]][1, 2, 3, 4, 5, 6, 7]
递归的思路就是,只要是列表,我就往下一层走。一直走到尽头,就是int的数值咯。

然后把这个数值收集起来+去掉这个数字的递归结果,返回给上一层。
感觉有点像2分。递归不要想,越想越乱,只要记住你到了最后一层,要做什么就行了。


2、

这个就吊了,我想了一个晚上还没想出来。

假设有个生成器:

def foo():    for i in range(10):        yield i
我们这么调用:

    for i in foo():        print i
就能不断拿到1至10。

现在请你给foo()加一个装饰器,使其每一次迭代能拿到[1,2]两个元素组成的list。

吊吧,装饰器+生成器,混在一起我还真的有点懵逼。

基本思路:装饰器修饰foo(),返回的应该还是必须个生成器。

def wrapper(func):    def new_func(*args, **kwargs):        a = func(*args, **kwargs)  # a还是个生成器        return a      return new_func@wrapperdef foo():    for i in range(10):        print "###",i        yield iif __name__ == '__main__':    for i in foo():        print i

以上代码只能保证加了装饰器的生成器不会出bug,但是真的不会改装呢,备份下,明天继续研究。

嗯,第二天开始谷歌了,还是没啥思路呢。要不赖皮点,这么写:

# coding=utf-8def wrapper(gen):    def new_gen(*args, **kwargs):        lst = list(gen(*args, **kwargs))        n = 4        return [lst[i:i+n] for i in range(0, len(lst), n)]    return new_gen@wrapperdef foo():    for i in range(10):        yield iif __name__ == '__main__':    for i in foo():        print i
结果:

[0, 1, 2, 3][4, 5, 6, 7][8, 9]
呵,实现是实现了,就是觉得傻逼。竟然先把这个生成器->list,然后对list等分。感觉这不是正确的解决方案。一定有正确的方法的。

想了下,装饰器返回一个生成器在,这个逻辑是不会错的。

def wrapper(gen):    def new_gen(*args, **kwargs):        g = gen(*args, **kwargs)        while True:             a,b,c,d = g.next(),g.next(),g.next(),g.next()            yield [a,b,c,d]    return new_gen@wrapperdef foo():    for i in range(10):        yield iif __name__ == '__main__':    for i in foo():        print i
结果:
[0, 1, 2, 3][4, 5, 6, 7]
哎,还是不大对的感觉,最后的[8,9]怎么搞?不过思路应该差不多,这里面是一个生成器了呢。




原创粉丝点击