Python中的列表推导式和生成器表达式 (List Comprehension & Generator Expressions)

列表(list)是pthon中最常用的数据结构之一,有序,可变。

 

1.生成一个列表最原始的方法

 

def is_leap(year: int):

    return year%4 == 0 and (year%100 != 0 or year%400 == 0)

 

Leap_Year_List = []    #空列表 或者用 Leap_Year_List = list()

 

for item in range(1582, 2022):

    if is_leap(item):

        Leap_Year_List.append(item)  #通过append方法填充列表元素

 

2.列表推导式(List Comprehension)

当然,还有其他的方法来生成列表,用列表推导式我们可以将上面的代码简化至一行:

Leap_Year_List =[item for item in range(1582, 2022) if is_leap(item)]  #通过for循环和if条件生成列表

 

note1: range()函数本身返回的也是整数列表

note2: 列表推导式里可以用多个for循环,返回的则是笛卡尔积

 

3.生成器表达式( Generator Expressions)

 

我们把列表表达式的[]换成()就得到了一个新的返回对象:生成器。

Leap_Year_Generator = (item for item in range(1582, 2022) if is_leap(item))   #得到生成器的这个方法称之为生成器表达式

 

所以,推导式和生成器类型不一样(一个是数据结构,一个是某种函数)导致它们的适用场景有所不同。生成含大量元素的列表会占用极大的内存空间,这种场景下一边循环一边计算效率更高。比如计算1到1,000,000,000的平方和,我们并不需要先得到一百万个元素的列表再求和,可以直接用生成器表达式来求和:

total = sum(num * num for num in range(1, 1000000000))

 

当列表是我们最终需要的结果时,用列表推导式;当列表只是我们运算的中间过程时,用生成器表达式。

 

note1: 生成器是一种特殊的迭代器。它的本质是一个能不断产生值的函数,它的意义在于提供了一种更为节省内存的方式去得到可迭代对象。

note2: 如果一个函数里有yield, 那它就是生成器。

note3: 迭代器是类,里面有数据成员(可迭代对象中的元素),有方法(iteration(),next())

 

 

4.拓展

举个生成器的例子:读取文本文件获得版本号

def get_version():

    with open("version.txt", "r") as fi:

        result = next(it for it in fi if it.startswith("__version__")) #生成器表达式

        # txt中内容为  __version__ = "1.0.1"

    return result.split('"')[1]   #结果为1.0.1

 

另一个例子:读取文本文件返回列表

def get_install_list():

    with open("sw_list.txt", "r") as fi:

        lines = fi.readlines()  

        #txt中为多行内容

    return [line.strip("\n") for line in lines if line] #列表推导式

 

posted @ 2021-02-03 19:00  henkenen  阅读(394)  评论(0编辑  收藏  举报