生成器小例子--把列表里面嵌套的sublist,顺序打印出来

生成器的优势

  1. 生成器是一种特殊的迭代器,不用去写一个有初始化_ _init_ _,_ _iter_ _,_ _ next__ 代码的可读性变高,更易读了,直接在普通函数上写
  2. 生成器它同样是不需要上来就开辟一大片空间,按需分配是最好的解答,你要多少,函数就一次一次地给你多少,一次执行了就等待下一次调用,然后再传回来值

例子:

遍历列表中的所有元素

第一个版本:
lista = [[1, 2], [3, 4], [5, 6]]


def flatten(list):
    for sublist in lista:
        for i in sublist:
            print(i)


flatten(list)

结果:
1
2
3
4
5
6

这是最最最简单的方法,我写一个函数,然后在函数里面直接打印出所有的元素,两次for 用起来,美滋滋,su服~,但是这段代码最尬的地方就是,复用性比较差,我要是要在别的地方用,比如我要给每个元素都加上1怎么办?这个函数我还能直接拿过来用吗?

第二个版本:解决复用性
lista = [[1, 2], [3, 4], [5, 6]]


def flatten(list):
    temp_list = []
    for sublist in lista:
        for i in sublist:
         temp_list.append(i)
    return temp_list


print(flatten(lista))

结果:[1, 2, 3, 4, 5, 6]

这段看上去不错哎~解决了复用性问题,比如我要再对这些数进行操作,就可以直接在返回的这个列表上进行操作了~美滋滋,但是问题又来了,我这一下子返回整个列表,我要是数字贼多,一下子不就崩了嘛?对的~接下来就轮到迭代器登场咯~

突然发现一个小问题,进行小补充:

如果列表有一个元素它不是嵌套的呢?

lista = [[1, 2], [3, 4], [5, 6], 5]


def flatten(list):
    temp_list = []
    for sublist in lista:
        try:
            for i in sublist:
                temp_list.append(i)
        except TypeError:
            temp_list.append(i)
    return temp_list


print(flatten(lista))

结果: [1, 2, 3, 4, 5, 6, 6]

用一个异常处理来解决。当不是可迭代对象的时候,也就是说单个数字不能拆分啦,就直接添加进列表里面,继续下一次循环。那么又有问题了。。如果里面有多层嵌套呢?
改进:应该可以用递归把

lista = [[1, 2], [3, 4], [5, 6], 5, [1, [2, 3]]]


def flatten(list):
    temp_list = []
    for sublist in list:
        try:
            for i in flatten(sublist):
                temp_list.append(i)
        except TypeError:
            temp_list.append(sublist)
    return temp_list


print(flatten(lista))
下面用生成器,对于这种for 用生成器真的是方便啊!而且还好用
def flatten(nested):
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested


lista = [[1, 2], 2, [3, 4], 5, [6, 7], [1, [2, 3]]]
for i in flatten(lista):
    print(i, end=' ')

结果:1 2 2 3 4 5 6 7 1 2 3

好用到哭啊,有没有啊!

最后补充一下自己对异常的又一次新的理解:

  当出现异常的时候(单个数字不是可迭代对象,不能再进行拆分)yield返回nested,返回到哪里去了呢?这里for element in flatten(sublist)这里的函数调用,就是in后面的,一开始不大清楚,用pass替代了yield element之后发现,怎么捣鼓也不输出值。
  然后又想了:抓到值之后呢?不是返回了一个数字嘛?在for element in flatten(sublist)里面不报错呢?神奇的地方!因为yield自动把nested变成了列表啦!请看!

        print(type(nested))
        yield nested
        print(type(nested))

结果:
< class ‘int’>
< class ‘list’>

又来补充咯~

  python基础书上说嘛,当遇到了字符串的时候会进入无限循环的,导致程序直接失败而崩溃,通过在stackoverflow上的提问,然后再加上自己的想法,最终得出了一个正确的方法:如下

def flatten(nested):
    try:
        if isinstance(nested, str):
            for i in nested:
                yield i
        else:
            for sublist in nested:
                for element in flatten(sublist):
                    yield element
    except TypeError:
        yield nested


lista = [[1, 2], 3, ['abc',[1, 'abc']]]
for i in flatten(lista):
    print(i)

结果:
1
2
3
a
b
c
1
a
b
c

这是一个成功解决含有字符串的版本。如果是字符串直接yield 字符串里面的每个元素,这样最终完成了这个。很奇妙吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河海哥yyds

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值