列表推导式(语法糖)

初看列表推导式可能会一头雾水,对词语法的可读性表示质疑,一旦理解语法糖后,你就会感觉出他那简短语句中的魅力。

使用方法

[迭代元素处理 for 迭代元素 in 可迭代对象 if 可迭代对象元素筛选条件] ->if 条件判断非必要

# 常规方法生成10以内的偶数,并将生成的偶数扩大一百倍
lis = []
for i in range(10):
    if i % 2 == 0:
        i = i * 100
        lis.append(i)
# 语法糖
syntactic_sugar = [i * 100 for i in range(10) if i % 2 == 0]
print(lis, syntactic_sugar)
# 输出:[0, 200, 400, 600, 800] [0, 200, 400, 600, 800]

如果觉得这样写语法糖过长可读性较差,我们可以对语法糖分行

syntactic_sugar = [i * 100
                   for i in range(10)
                   if i % 2 == 0]

优先看in之后的迭代对象是什么,之后看if后的条件,会取出那些迭代对象,最看第一行中对取出的迭代对象会做如何处理
在语法糖开头的i可以是一个判断语句,这时候列举就会输出对所以符合if条件的迭代对象的判断结果

syntactic_sugar = [i * 100 > 500 for i in range(10) if i % 2 == 0]          
print(lis, syntactic_sugar) # [False, False, False, True, True]

并且列表推导式可以嵌套使用假设第一次迭代输出的元素还是可迭代对象,还可以在进行for in进行再次迭代。

使用方式推广

语法糖不仅可以用于列表,还能用于字典与集合,集合的使用方式和列表类似,只是吧[中括号]换成{大括号},不过字典使用的时候要注意,迭代字典(dict)类型时候,默认只读取为.keys()方法,如果想要读取所有内容,需要在迭代对象后加.items方法

# 使用字典的语法糖将键值调换位置
dic = {'姓名': '寻觅',
       '年龄': '20',
       '现状': '单身',
       '需求': '女票',
       '急迫程度': '高'
       }

syntactic_sugar = {value: key for key, value in dic.items()}

这时候你会想[中括号]是列表的语法糖,{大括号}是字典与集合的语法糖,哪(小括号)会不会生成元组的语法糖?
如果你这样想,哪很不幸的告诉你,你想错了,如果我们将列表推广式的中括号改为小括号你会惊奇的发现,它输出的竟然是一个地址
在这里插入图片描述

syntactic_sugar = (i for i in range(10) if i % 2 == 0)
print(syntactic_sugar) # <generator object <genexpr> at 0x00000182C27A5F90>

我们获得的输出并不是我们想要的值而变成了一个(generator)生成器类型的地址。

生成器

生成器是迭代器的一种,可以做可控的迭代行为,生成器用多少做多少的行为可以避免资源的浪费,假设我们现在生成一个包含数百个数据的列表,但我们可能当下只会用到前几个数据,选择生成器就可以优化生成数据的占用情况。

使用方法

除了上述将列表推导式的[中括号]变为(小括号)后会获得列表推广式,我们还可以在函数中使用yield返回值函数做生成器,函数中每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。

def generator(loop_max):
    """
    使用斐波那契数列来展示生成器的作用1,1,2,3,5,8,12,21,34.....
    :param loop_max: 斐波那契数列的最大输出值
    :return:使用yield输出斐波那契数列
    """
    l, x, y = 0, 0, 1
    while loop_max > l:
        yield y
        x, y = y, x + y
        l += 1
items = generator(10)
# 直接输出生成器会是一个地址,这个地址存储着生成输出内容的算法,相较于直接输出,更加节省内存,逐个输出生成器内容有三种方式。
# ".send(None)",".__next__()","next()"
print(items)
print(items.send(None))
print(items.__next__())
print(next(items))
print('可以中途执行其他命令')
print(items.send(None))
print(items.__next__())
print(next(items))
print('生成器是可迭代对象')
for i in items:
    print(i)
# 将数值全部取完后在使用next会报错“StopIteration”
# print(items.__next__())

输出内容为
在这里插入图片描述
而从列表推导式变化过来的生成器,每迭代一次后都相当于执行了yield。
generator = (i for i in range(10) if i % 2 == 0)
在这里插入图片描述
上述代码截图中出现的字体的连体符使用的是火狐的编程字体,具体的下载地址和设置方法可以在为编程而生的字体(附网盘下载链接),Pycharm神器级插件 我这篇博客中查看