24/9/21 python的推导式、生成器

python推导式和生成器

介绍

1. 列表推导式(List Comprehension)

列表推导式是最常见的一种推导式,它允许你用一行代码生成列表,形式如下:

new_list = [expression for item in iterable if condition]
  • expression:要添加到新列表的值,可以是简单的变量,也可以是运算结果。
  • item:来自迭代对象的每个元素。
  • iterable:任何可迭代对象(如列表、字符串、range 等)。
  • if condition:可选,用来筛选符合条件的元素。

示例:

生成一个包含平方数的列表:

squares = [x**2 for x in range(10)]
print(squares)  # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

2. 字典推导式(Dictionary Comprehension)

字典推导式与列表推导式类似,只不过它生成的是字典,格式如下:

new_dict = {key: value for item in iterable}

示例:

生成一个键为数字,值为其平方的字典:

squares_dict = {x: x**2 for x in range(5)}
print(squares_dict)  # 输出 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

3. 集合推导式(Set Comprehension)

集合推导式的语法与列表推导式类似,但生成的结果是集合。

new_set = {expression for item in iterable if condition}

示例:

生成一个不重复的平方数集合:

squares_set = {x**2 for x in range(5)}
print(squares_set)  # 输出 {0, 1, 4, 9, 16}

4. 生成器表达式(Generator Expression)

生成器表达式和列表推导式类似,但它不直接生成列表,而是返回一个生成器对象,用于惰性求值,适合处理大量数据。

gen = (x**2 for x in range(10))
print(list(gen))  # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

5. 嵌套推导式

推导式也可以嵌套,用于生成复杂的结构。

示例:

生成一个二维列表:

matrix = [[i * j for j in range(3)] for i in range(3)]
print(matrix)  # 输出 [[0, 0, 0], [0, 1, 2], [0, 2, 4]]

总结:

推导式使代码更加简洁、可读,并且在处理生成列表、字典或集合时特别高效。不过,推导式过于复杂时可能会影响代码的可读性,需谨慎使用。

1. 什么是生成器?

生成器(Generator) 是 Python 中一种特殊类型的迭代器,用于生成一系列的值。在常规的函数中,使用 return 来返回值并结束函数,而在生成器中,使用 yield 来逐次生成值,而不终止函数。生成器可以暂停函数的执行,并在下一次迭代时恢复执行,这种特性使得它适用于处理大量数据或无限数据流。

生成器的定义:

  • 生成器可以通过生成器函数创建,使用 yield 语句。
  • 生成器也可以通过生成器表达式创建,类似于列表推导式,但使用圆括号代替方括号。

生成器函数示例:

def my_generator():
    yield 1
    yield 2
    yield 3

gen = my_generator()
for value in gen:
    print(value)

2. 生成器与列表的区别

  • 内存占用

    • 生成器是惰性求值的,这意味着它们不会一次性把所有的值加载到内存中,而是每次需要时才生成下一个值,因此非常节省内存。
    • 列表则会在创建时一次性将所有元素加载到内存中,尤其是当数据量很大时,可能导致大量的内存占用。
  • 求值方式

    • 生成器是惰性求值的(即在需要时才生成下一个值),而列表是即时求值的(一次性生成整个列表的所有值)。
  • 可重复使用

    • 生成器一旦迭代完毕,就不能再次使用,除非重新创建。
    • 列表可以多次迭代,因为它们的所有元素都存储在内存中。

列表与生成器的对比:

# 列表
lst = [x**2 for x in range(5)]
print(lst)  # 输出: [0, 1, 4, 9, 16]

# 生成器
gen = (x**2 for x in range(5))
print(list(gen))  # 输出: [0, 1, 4, 9, 16]

生成器不占用大量内存,但在将生成器转换为列表时,才会将所有值存储在内存中。

3. 什么是惰性求值?

惰性求值(Lazy Evaluation),也叫延迟求值,是一种计算策略,指的是当值真正被需要时才进行计算,而不是在定义时立即计算。这使得生成器可以在处理大量数据或无限序列时显得特别高效。

惰性求值的好处:

  • 节省内存:生成器不会立即生成所有元素,只在迭代到某个值时才计算它,因此适合处理大规模或无限数据流。
  • 提高效率:通过按需生成数据,避免了不必要的计算和内存占用。

示例:

def count_up_to(n):
    count = 1
    while count <= n:
        yield count
        count += 1

counter = count_up_to(5)
print(next(counter))  # 1
print(next(counter))  # 2
# 生成器不会计算后续的值,直到你需要它们为止

在此例中,生成器在调用 next() 时才生成下一个值,未被调用时不会生成,因此更高效。

总结:

  • 生成器是惰性求值的迭代器,用来节省内存并延迟计算。
  • 列表是立即求值的,它会一次性加载所有元素。
  • 惰性求值是指在需要时才进行计算,而不是立即执行,从而提高性能和内存使用效率。

生成器特别适用于大规模或无限序列的处理场景,因为它们仅在需要时生成数据,非常节省内存。

本文作者:Gold_stein

本文链接:https://www.cnblogs.com/smartljy/p/18424486

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Gold_stein  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 逃离地面 RAD & 三浦透子
逃离地面 - RAD & 三浦透子
00:00 / 00:00
An audio error has occurred.

作词 : 野田洋次郎

作曲 : 野田洋次郎

空飛ぶ羽根と引き換えに 繋ぎ合う手を選んだ僕ら

それでも空に魅せられて 夢を重ねるのは罪か

夏は秋の背中を見て その顔を思い浮かべる

憧れなのか、恋なのか 叶わぬと知っていながら

重力が眠りにつく 1000年に一度の今日

太陽の死角に立ち 僕らこの星を出よう

彼が眼を覚ました時 連れ戻せない場所へ

「せーの」で大地を蹴って ここではない星へ

行こう

もう少しで運命の向こう もう少しで文明の向こう

もう少しで運命の向こう もう少しで

夢に僕らで帆を張って 来たるべき日のために夜を超え

いざ期待だけ満タンで あとはどうにかなるさと 肩を組んだ

怖くないわけない でも止まんない

ピンチの先回りしたって 僕らじゃしょうがない

僕らの恋が言う 声が言う

「行け」と言う