百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python不允许你不知道的 9大高效迭代技巧

myzbx 2025-08-31 06:17 8 浏览


#每天一个编程技巧#掌握高效的迭代技巧可以显著提升Python代码的性能和可读性。以下是Python中各种高效迭代的方法和技巧:

1. 基本迭代优化

1.1 使用enumerate()获取索引和值

# 传统方式(不推荐)
for i in range(len(items)):
    print(i, items[i])

# Pythonic方式
for i, item in enumerate(items):
    print(i, item)

# 指定起始索引
for i, item in enumerate(items, start=1):
    print(f"Item {i}: {item}")

1.2 使用zip()并行迭代

names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]

# 并行迭代多个序列
for name, age in zip(names, ages):
    print(f"{name} is {age} years old")

# 处理不等长序列
from itertools import zip_longest
for name, age in zip_longest(names, ages, fillvalue='Unknown'):
    print(f"{name}: {age}")

2. 高级迭代技巧

2.1 使用itertools模块

from itertools import islice, cycle, repeat, chain

# islice - 迭代切片
for item in islice(range(100), 5, 10):  # 获取5-9项
    print(item)

# cycle - 无限循环迭代
count = 0
for item in cycle(['a', 'b', 'c']):
    print(item)
    count += 1
    if count > 5: break

# repeat - 重复元素
for item in repeat('Python', 3):  # 重复3次
    print(item)

# chain - 连接多个可迭代对象
for item in chain([1, 2], ['a', 'b'], [True, False]):
    print(item)

2.2 使用生成器表达式

# 列表推导式(立即求值)
squares = [x**2 for x in range(10000)]  # 占用内存

# 生成器表达式(惰性求值)
squares_gen = (x**2 for x in range(10000))  # 节省内存

# 在函数中使用
total = sum(x**2 for x in range(10000))  # 更高效

3. 字典迭代技巧

3.1 高效字典迭代方法

d = {'a': 1, 'b': 2, 'c': 3}

# 迭代键
for key in d:  # 等同于 d.keys()
    print(key)

# 迭代值
for value in d.values():
    print(value)

# 迭代键值对
for key, value in d.items():  # Python 3中items()是高效的
    print(key, value)

3.2 字典推导式

# 创建新字典
squares = {x: x**2 for x in range(5)}

# 交换键值
inverted = {v: k for k, v in d.items()}

# 条件筛选
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}

4. 文件高效迭代

4.1 逐行读取大文件

# 低效方式(整个文件读入内存)
with open('large_file.txt') as f:
    lines = f.readlines()  # 可能内存不足
    for line in lines:
        process(line)

# 高效方式(逐行迭代)
with open('large_file.txt') as f:
    for line in f:  # 文件对象本身就是可迭代的
        process(line)

4.2 使用生成器处理文件

def read_in_chunks(file_object, chunk_size=1024):
    """生成器函数:按块读取文件"""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data

with open('huge_file.bin', 'rb') as f:
    for chunk in read_in_chunks(f):
        process(chunk)

5. 条件迭代技巧

5.1 使用filter()和map()

def read_in_chunks(file_object, chunk_size=1024):
    """生成器函数:按块读取文件"""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data

with open('huge_file.bin', 'rb') as f:
    for chunk in read_in_chunks(f):
        process(chunk)

5.2 使用any()和all()短路评估

# any - 任意元素为True时停止迭代
has_positive = any(x > 0 for x in numbers)

# all - 所有元素为True时返回True
all_positive = all(x > 0 for x in numbers)

6. 嵌套结构迭代

6.1 扁平化嵌套迭代

from collections.abc import Iterable

def flatten(items):
    """递归扁平化嵌套结构"""
    for item in items:
        if isinstance(item, Iterable) and not isinstance(item, (str, bytes)):
            yield from flatten(item)
        else:
            yield item

nested = [1, [2, [3, 4], 5]]
flat_list = list(flatten(nested))  # [1, 2, 3, 4, 5]

6.2 使用itertools.product多重循环

from itertools import product

# 替代多重嵌套循环
for x, y, z in product(range(2), range(2), range(2)):
    print(x, y, z)  # 相当于三重嵌套循环

# 计算笛卡尔积
colors = ['red', 'green']
sizes = ['S', 'M', 'L']
for color, size in product(colors, sizes):
    print(color, size)

7. 性能优化技巧

7.1 避免在循环中重复计算

# 不推荐
for item in data:
    result = complex_calculation(item) * factor + offset

# 推荐 - 预先计算不变的部分
adjusted_factor = factor * offset
for item in data:
    result = complex_calculation(item) * adjusted_factor

7.2 使用局部变量加速访问

# 不推荐
for item in large_list:
    value = math.sqrt(item) + math.sin(item)

# 推荐 - 局部变量访问更快
sqrt = math.sqrt
sin = math.sin
for item in large_list:
    value = sqrt(item) + sin(item)

7.3 使用__slots__减少内存占用

class Point:
    __slots__ = ['x', 'y']  # 固定属性列表,减少内存
    
    def __init__(self, x, y):
        self.x = x
        self.y = y

points = [Point(i, i*2) for i in range(100000)]  # 比普通类更省内存

8. 自定义可迭代对象

8.1 实现迭代器协议

class CountDown:
    def __init__(self, start):
        self.current = start
    
    def __iter__(self):
        return self
    
    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        num = self.current
        self.current -= 1
        return num

for num in CountDown(5):
    print(num)  # 5,4,3,2,1

8.2 生成器函数

def fibonacci(limit):
    a, b = 0, 1
    while a < limit:
        yield a
        a, b = b, a + b

for num in fibonacci(100):
    print(num)  # 0,1,1,2,3,5,8,13,21,34,55,89

9. 实用工具函数

9.1 使用collections.defaultdict

from collections import defaultdict

# 自动初始化字典值
word_counts = defaultdict(int)
for word in words:
    word_counts[word] += 1  # 无需检查键是否存在

# 分组功能
groups = defaultdict(list)
for item in data:
    groups[item.category].append(item)

9.2 使用functools.reduce

from functools import reduce

# 累积计算
product = reduce(lambda x, y: x * y, [1, 2, 3, 4])  # 24

# 更复杂的归约
def factorial(n):
    return reduce(lambda a, b: a * b, range(1, n+1), 1)

掌握这些高效迭代技巧可以让你写出更Pythonic、性能更好的代码。记住,在Python中,显式的循环通常比隐式的循环慢,所以尽量使用内置函数和生成器表达式来处理迭代任务。

相关推荐

半导体行业术语缩写词典总结-JKL_半导体词汇缩写表

作为半导体行业新人来说,最痛苦的莫过于各种缩写词术语了,有的缩写词一样但是会有不同的解释。这里作者给大家整理了部分术语词典,后面会按照更新顺序一一分享出来。废话不多说,直接开始,如有遗漏,欢迎大家在评...

JD.com Deepens Push Into Embodied Intelligence With Investment in Sensor Maker PaXiniTech

ToraOne,thesecond-generationmultidimensionaltactilehumanoidrobotdevelopedbyPaXiniTechTMTPOS...

Hong Kong&#39;s Consumer Market Becomes New Battleground for Chinese Mainland Internet Giants

AI-generatedimageTMTPOST--StrollthroughthestreetsofHongKongtoday,anditmightfeellikey...

http2解决了哪些问题_简述http2的优点

HTTP/2(最初称为SPDY)是HTTP协议的第二个主要版本,它在HTTP/1.1的基础上进行了重大改进,旨在解决其在性能和效率方面的诸多瓶颈。以下是HTTP/2主要解决的问题:队头阻...

China&#39;s economy stays strong and vital amid pressure

Peoplevisitthe4thChina-CEECExpo&InternationalConsumerGoodsFairinNingbo,eastChina's...

JD.com Makes $2.4 Billion Bid for Ceconomy in Bold Push to Build a Global Retail Empire

TMTPOST--JD.comhasunveiledplanstoacquireGermany’sCeconomyAG—theparentofEurope’sleading...

深入剖析 Java 中的装饰器设计模式:原理、应用与实践

在Java软件开发的广阔天地里,设计模式犹如璀璨星辰,照亮我们构建高效、可维护系统的道路。今天,让我们聚焦于其中一颗闪耀的星——装饰器设计模式,深入探究它的奥秘,看看如何利用它为我们的代码赋予...

组合模式应用-适配器模式_适配器组件

写在前面Hello,我是易元,这篇文章是我学习设计模式时的笔记和心得体会。如果其中有错误,欢迎大家留言指正!该部分为各模式组合使用,涉及代码较多,熟能生巧。内容回顾定义适配器模式是一种结构型设计模式,...

OOM (Out Of Memory) 故障排查指南

1.确认OOM类型首先需要确认是哪种类型的OOM:JavaHeapOOM:Java堆内存不足NativeMemoryOOM:本地内存不足MetaspaceOOM:元空间内存不足Contai...

刷完这49题,面试官当场给Offer!Java程序员必备指南

1.问题:如果main方法被声明为private会怎样?答案:能正常编译,但运行的时候会提示”main方法不是public的”。2.问题:Java里的传引用和传值的区别是什么?答案:传引用是指传递的是...

C#编程基础(看这一篇就够了)_c#编程入门与应用

C#及其开发环境简介C#概述C#是一个现代的、通用的、面向对象的编程语言,由微软(Microsoft)开发,经Ecma和ISO核准认可。它由AndersHejlsberg和他的团队在.NET框架开发...

说一下JDK的监控和 线上处理的一些case

一句话总结JDK监控常用工具包括JConsole、VisualVM、JMC等,用于实时查看内存、线程、GC状态。线上常见问题处理:内存泄漏通过heapdump分析对象引用链;频繁GC可调整-Xmx/...

JavaScript深拷贝极简指南:3种方法解决嵌套与循环引用难题

为什么需要深拷贝?首先我们看看浅拷贝,point指向的是同一个地址,这时我们修改obj2.point的属性时,obj1的point属性也会被修改再看看深拷贝,point指向的是不同地址,这时我们修改o...

Java 25 在 JEP 519 中集成了紧凑对象头

作者|ANMBazlurRahman译者|刘雅梦策划|丁晓昀Java25通过JEP519将紧凑对象头作为产品特性进行了集成,在不需要更改任何代码的情况下,为开发人员提供了...

每日一练 Python 面试题(1)_python每日一记

以下是5道Python基本语法相关的面试题,涵盖变量、运算符、数据结构、函数和异常处理等核心概念:1.变量与作用域题目:以下代码的输出是什么?解释原因。x=10deffunc():...