Python进阶编程:编写更高效、优雅的Python代码
上QQ阅读APP看书,第一时间看更新

4.1.4 反向迭代

在实际应用中,将一个序列逆序输出是比较常见的操作。对于迭代,这种操作称为反方向迭代。

对于反向迭代序列,我们可以使用内置的reversed()函数,代码(reversed_iter.py)如下:


a = [1, 2, 3, 4]
print(f'primary a is: {a}')
b = list()
for x in reversed(a):
    b.append(x)
print(f'{a} reversed is: {b}')

执行py文件,输出结果如下:


primary a is: [1, 2, 3, 4]
[1, 2, 3, 4] reversed is: [4, 3, 2, 1]

反向迭代仅仅当对象的大小可预先确定或者对象实现了__reversed__()函数才生效。如果两者都不符合,必须先将对象转换为一个列表,代码如下:


f = open('/etc/passwd')
for line in reversed(list(f)):
    print(line, end='')

注意 如果可迭代对象元素很多,将其预先转换为一个列表要消耗大量的内存。

我们可以通过在自定义类上实现__reversed__()方法来实现反向迭代,代码(reversed_iter.py)示例如下:


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

    # Forward iterator
    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

    # Reverse iterator
    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

for rev_val in reversed(Countdown(20)):
    print(f'reversed order: {rev_val}')
print()
for nor_val in Countdown(20):
    print(f'normal order: {nor_val}')

执行py文件,输出结果如下:


reversed order: 1
reversed order: 2
...
reversed order: 20

normal order: 20
normal order: 19
...
normal order: 1

定义一个反向迭代器可以使代码运行非常高效,因为不再需要将数据填充到一个列表中,然后再去反向迭代该列表。