首页 > 编程语言 >24/9/21 python的推导式、生成器

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

时间:2024-09-21 20:45:14浏览次数:9  
标签:24 推导 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() 时才生成下一个值,未被调用时不会生成,因此更高效。

总结:

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

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

标签:24,推导,python,生成器,列表,内存,求值,生成
From: https://www.cnblogs.com/smartljy/p/18424486

相关文章