【Python】迭代器、生成器、表达式


列表推导式

列表推导式是Python中快速生成列表的一种方法,它允许你使用可迭代对象快速生成一个列表,可以替代简单的循环语句。

基本结构:[expression for item in iterable if condition]

  • expression:基于迭代变量,可以是任何Python表达式,如元组,集合等。
  • item:迭代器返回的项目。
  • iterable:Python中可迭代对象,包括有内置的五个数据结构,文件对象,生成器,以及其他内置迭代器(如,range,zip,map,filter等),还有自定义迭代器,外部库中的可迭代对象等
  • condition:可选的条件语句。
# 包含条件的列表推导式
even_squares = [x*x for x in range(10) if x % 2 == 0]
print(even_squares)  # 输出: [0, 4, 16, 36, 64]

# 等价下列程序(可根据这个理解)
even_squares = []
for x in range(10):
    if x % 2 == 0:
        even_squares.append(x*x)

print(even_squares)  # 输出: [0, 4, 16, 36, 64]

# 使用元组表达式
even_squares = [(x, x*x) for x in range(10) if x % 2 == 0]
print(even_squares)  # 输出: [(0, 0), (2, 4), (4, 16), (6, 36), (8, 64)]

除了基本的列表推导式,Python还支持嵌套列表推导式

你可以在列表推导式中使用多个循环,实现更复杂的迭代逻辑。

# 使用嵌套列表推导式处理二维数组
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened)  # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 它也可以进行拆分理解

迭代器

迭代器是Python中一个实现了迭代器协议的对象,这包括__iter__()__next__()两个方法。迭代器允许程序员在容器(如列表或字典)上进行遍历。

迭代器的工作原理:

  • __iter__()方法返回迭代器对象本身。
  • __next__()方法返回容器的下一个项目。当容器中没有更多元素时,__next__()应该抛出一个StopIteration异常。

创建自定义迭代器的示例:

class Countdown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        else:
            num = self.current
            self.current -= 1
            return num

# 使用迭代器
counter = Countdown(5)
for num in counter:
    print(num)

生成器

生成器是一种特殊类型的迭代器,它通过一个包含yield语句的函数定义。当生成器函数被调用时,它不会立即执行,而是返回一个生成器对象。这个对象在迭代时才真正执行函数内的代码。

每次调用next()方法(或在for循环中迭代)时,my_generator函数执行到下一个yield语句并暂停执行,返回yield后的值。当再次被调用时,从上次离开的地方继续执行。

def my_generator():
    yield 'a'
    yield 'b'
    yield 'c'

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

生成器使用迭代来处理数据,这意味着在任何时候内存中只有一个数据项被处理,这个特点使他成为处理大型数据集时的理想选择,例如大型文件或网络流。

def read_large_file(file_name):
    with open(file_name, 'r') as file:
        for line in file:
            yield line.strip()

log_lines = read_large_file('large_log_file.log')
for line in log_lines:
    if "ERROR" in line:
        print(line)

生成器yield与return之间的比较:

1. return

return语句用于从函数返回一个值,结束函数的执行。当一个函数执行到return语句时,函数的局部变量的生命周期结束,控制流返回到函数被调用的地方。

  • 终结执行:执行到return语句时,函数的执行立即结束。
  • 返回值:可以返回一个值或None(如果没有指定返回值)。
  • 单次使用:函数中可以有多个return语句,但只有一个return语句会被执行。
def sum_two_numbers(a, b):
    return a + b
    return a - b

result = sum_two_numbers(5, 3)
print(result)  # 输出: 8

2. yield

yield语句用于从一个函数返回一个值,并暂停函数的执行,即函数的状态被冻结,包括所有变量的值和指令指针的位置。yield通常用于创建生成器。

  • 暂停执行yield返回一个值后,函数的执行被暂停,保留当前所有变量的状态,直到再次调用时从上次离开的地方继续执行。
  • 多次使用:函数可以包含多个yield语句。每次通过迭代器请求值时,函数执行到下一个yield语句并再次暂停。
  • 不终结执行:使用yield的函数在提供值后,并未完全结束,而是等待下一次迭代。
def count_down(start):
    while start > 0:
        yield start
        start -= 1

for number in count_down(5):
    print(number)
# 输出:
# 5
# 4
# 3
# 2
# 1

生成器表达式

生成器表达式提供了一种语法更为紧凑的方式来创建生成器,它们的语法和列表推导式非常相似,但使用圆括号而不是方括号。生成器表达式适用于快速生成数据而不需要存储全部数据的情况。

基本结构:(expression for item in iterable if condition)

  • expression:基于迭代变量,可以是任何Python表达式,如元组,集合等。
  • item:迭代器返回的项目。
  • iterable:Python中可迭代对象,包括有内置的五个数据结构,文件对象,生成器,以及其他内置迭代器(如,range,zip,map,filter等),还有自定义迭代器,外部库中的可迭代对象等
  • condition:可选的条件语句。
squares = (x*x for x in range(10))
for square in squares:
    print(square, end=" ")
# 0 1 4 9 16 25 36 49 64 81

列表推导式与生成表达式的比较:

# 列表推导式
square_list = [x*x for x in range(10)]
# 生成器表达式
square_gen = (x*x for x in range(10))
  • 当你使用列表推导式时,Python会立即执行其中的表达式,生成列表中的所有元素,并将这些元素存储在内存中。这使得列表推导式非常快,因为它立即提供了一个完整的列表,但这种方法也可能消耗大量内存,特别是当列表非常大时。
  • 生成表达式则是返回一个生成器对象,该对象按需生成元素。这意味着元素只有在迭代时才被计算的,而不是在生成器表达式被定义时。这种方法可以显著降低内存使用,因为在任何时刻,只有一个元素被存储在内存中。
  • 54
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值