Python中for循环遍历列表元组字典集合的实用技巧

 更新时间:2026年07月13日 08:58:24   作者:星河耀银海  
本文将手把手教你掌握Python中for循环的核心技巧,从列表、元组到字典、集合,甚至嵌套遍历和for-else语句,让你轻松应对90%以上的循环场景,写出简洁高效的Python代码

一、开篇:Python中最常用的循环

如果说while循环是"条件驱动"的循环,那么for循环就是"数据驱动"的循环——它天然适合遍历集合中的每一个元素。在Python中,for循环是绝对的主力循环结构,你在日常编码中90%以上的循环都是for循环。

for循环在Python中的设计哲学与众不同:

# Python的for循环——遍历可迭代对象中的每一个元素
fruits = ["苹果", "香蕉", "橘子"]
for fruit in fruits:
    print(fruit)

# 不是其他语言中那种"计数器for循环"
# for (int i = 0; i < 10; i++) { ... }  ← 这是C/Java的写法
# Python用 for i in range(10): 替代

Python的for循环之所以强大,是因为它建立在迭代器协议之上——几乎所有的容器类型(列表、元组、字典、集合、字符串)都是可迭代的,都可以被for循环直接遍历。今天我们就来全面掌握for循环遍历各种数据结构的技巧。

二、for循环的基本结构

2.1 基本语法

# for循环的基本语法
# for 变量 in 可迭代对象:
#     循环体
# else:              # 可选
#     else代码块

# 最简单的例子
fruits = ["苹果", "香蕉", "橘子", "葡萄", "西瓜"]
for fruit in fruits:
    print(f"我喜欢吃{fruit}")

# 输出:
# 我喜欢吃苹果
# 我喜欢吃香蕉
# 我喜欢吃橘子
# 我喜欢吃葡萄
# 我喜欢吃西瓜

# 遍历字符串(字符串也是可迭代对象)
for char in "Python":
    print(char, end=' ')
# 输出: P y t h o n

2.2 for循环的本质

# for循环的底层机制:
# 1. 调用 iter(可迭代对象) 获取迭代器
# 2. 反复调用 next(迭代器) 获取下一个值
# 3. 遇到 StopIteration 异常时停止

# 手动模拟for循环的执行过程
fruits = ["苹果", "香蕉", "橘子"]

# for fruit in fruits 等价于:
iterator = iter(fruits)
while True:
    try:
        fruit = next(iterator)
        print(fruit)
    except StopIteration:
        break

# 了解这个机制很重要,因为它解释了:
# - 为什么for可以遍历任何实现了__iter__的对象
# - 为什么可以在遍历时获取下一个元素(迭代器是有状态的)
# - 为什么生成器可以和for循环无缝配合

2.3 for循环中修改变量不影响原数据

# 在for循环中修改循环变量,不会影响迭代过程
# 因为每次迭代都是从迭代器中获取下一个值

numbers = [1, 2, 3, 4, 5]
for n in numbers:
    print(f"当前: {n}", end=' → ')
    n = n * 10    # 修改循环变量
    print(f"修改后: {n}")

print(f"\n原列表不变: {numbers}")  # [1, 2, 3, 4, 5]

# 如果你想修改原列表的元素,需要通过索引
for i in range(len(numbers)):
    numbers[i] = numbers[i] * 10
print(f"通过索引修改: {numbers}")  # [10, 20, 30, 40, 50]

三、遍历列表

3.1 基础遍历

# 直接遍历列表元素(最常用)
fruits = ["苹果", "香蕉", "橘子", "葡萄"]
for fruit in fruits:
    print(fruit)

# 遍历 + 条件判断
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = []
for n in numbers:
    if n % 2 == 0:
        even_numbers.append(n)
print(f"偶数: {even_numbers}")

# 遍历 + 累积
total = 0
for price in [19.9, 29.9, 39.9, 49.9]:
    total += price
print(f"总价: {total:.1f}")

3.2 需要索引的遍历方式

fruits = ["苹果", "香蕉", "橘子", "葡萄", "西瓜"]

# 方式1:使用range(len()) —— C风格,不推荐
for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# 方式2:使用enumerate() —— 推荐!✅
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

# 方式3:指定起始索引
for i, fruit in enumerate(fruits, start=1):
    print(f"第{i}个: {fruit}")

# enumerate的实际应用:同时需要值和位置
def find_all_occurrences(items, target):
    """找到所有匹配项的索引"""
    return [i for i, item in enumerate(items) if item == target]

data = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
print(find_all_occurrences(data, 5))  # [4, 8, 10]

3.3 遍历时修改列表

# ⚠️ 重要:遍历列表时不要直接修改列表长度!
# 这会导致不可预期的行为

# ❌ 错误示例:遍历时删除元素
# numbers = [1, 2, 3, 4, 5]
# for n in numbers:
#     if n % 2 == 0:
#         numbers.remove(n)  # 危险!
# print(numbers)  # [1, 3, 5] —— 碰巧对了,但不能依赖
# # 实际上如果连续两个偶数,会漏删第二个!

# ❌ 错误示例:遍历时添加元素 → 无限循环!
# for n in numbers:
#     numbers.append(n * 10)   # 永远不会结束!

# ✅ 正确方式1:遍历副本
numbers = [1, 2, 3, 4, 5]
for n in numbers[:]:    # numbers[:] 创建了副本
    if n % 2 == 0:
        numbers.remove(n)
print(numbers)  # [1, 3, 5]

# ✅ 正确方式2:列表推导式(创建新列表)
numbers = [1, 2, 3, 4, 5]
numbers = [n for n in numbers if n % 2 != 0]
print(numbers)  # [1, 3, 5]

# ✅ 正确方式3:反向遍历删除(通过索引)
numbers = [1, 2, 3, 4, 5]
for i in range(len(numbers) - 1, -1, -1):
    if numbers[i] % 2 == 0:
        del numbers[i]
print(numbers)  # [1, 3, 5]

四、遍历元组

4.1 基本遍历

# 遍历元组和遍历列表完全一样
colors = ("红色", "绿色", "蓝色", "黄色")
for color in colors:
    print(color)

# 元组不可修改,所以不会遇到"遍历时修改"的问题
# 这是元组在循环中的一个"安全优势"

4.2 元组解包遍历

# 当元组中的元素也是元组时,解包非常方便
coordinates = [(1, 2), (3, 4), (5, 6), (7, 8)]

# 直接在for循环中解包
for x, y in coordinates:
    print(f"坐标: ({x}, {y}), 距离原点: {(x**2 + y**2)**0.5:.2f}")

# 三层解包
students = [
    ("张三", 85, 92),
    ("李四", 78, 88),
    ("王五", 92, 95),
]
for name, math, english in students:
    avg = (math + english) / 2
    print(f"{name}: 数学{math}, 英语{english}, 平均{avg:.1f}")

# 部分解包 + * 收集
data = [(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)]
for first, second, *rest in data:
    print(f"前两个: ({first}, {second}), 剩余: {rest}")

五、遍历字典

5.1 字典遍历的三种方式

user = {
    "name": "张三",
    "age": 25,
    "city": "北京",
    "email": "zhangsan@example.com",
    "phone": "13800138000",
}

# 方式1:遍历键(默认)
print("=== 遍历键 ===")
for key in user:            # 等价于 for key in user.keys()
    print(f"  {key}")

# 方式2:遍历值
print("\n=== 遍历值 ===")
for value in user.values():
    print(f"  {value}")

# 方式3:遍历键值对(最常用)
print("\n=== 遍历键值对 ===")
for key, value in user.items():
    print(f"  {key}: {value}")

5.2 items()解包遍历

# items()返回的是dict_items视图对象
# 每个元素是一个(key, value)元组
# 在for循环中可以直接解包

config = {
    "host": "localhost",
    "port": 8080,
    "debug": True,
    "timeout": 30,
}

# 解包遍历(推荐写法)
for key, value in config.items():
    print(f"{key:12} = {value}")

# 如果要同时获取索引
for i, (key, value) in enumerate(config.items()):
    print(f"{i}: {key} = {value}")

# 筛选遍历
for key, value in config.items():
    if isinstance(value, bool):
        print(f"布尔配置: {key} = {value}")
    elif isinstance(value, int):
        print(f"数值配置: {key} = {value}")

5.3 字典遍历的性能考量

# 大数据量时,选择合适的遍历方式
import timeit

# 构建大字典
large_dict = {i: i**2 for i in range(100000)}

# 只遍历键
t_keys = timeit.timeit(lambda: [k for k in large_dict], number=100)
print(f"遍历键: {t_keys:.3f}s")

# 遍历键值对
t_items = timeit.timeit(lambda: [(k, v) for k, v in large_dict.items()], number=100)
print(f"遍历键值对: {t_items:.3f}s")

# 遍历值
t_values = timeit.timeit(lambda: [v for v in large_dict.values()], number=100)
print(f"遍历值: {t_values:.3f}s")

# 📝 注意:
# - keys()、values()、items() 返回的是视图对象,不是拷贝
# - 遍历时不会额外占用大量内存
# - 但如果要多次遍历,可以先转为list

六、遍历集合

6.1 基本遍历

# 集合的遍历——无序但高效
fruits = {"苹果", "香蕉", "橘子", "葡萄"}

for fruit in fruits:
    print(fruit)
# 输出顺序不固定!

# 如果需要有序遍历,用sorted()
for fruit in sorted(fruits):
    print(fruit)
# 现在按字母/拼音顺序输出

# 集合遍历的特点:
# 1. 每个元素只出现一次(重复自动去除)
# 2. 顺序不确定(哈希表实现)
# 3. O(1) 的成员检查(比列表O(n)快得多)

6.2 集合运算在循环中的应用

# 集合运算配合循环
all_users = {"张三", "李四", "王五", "赵六", "钱七"}
vip_users = {"张三", "赵六", "孙八"}
banned_users = {"李四", "钱七"}

# 找出所有正常用户
normal_users = all_users - banned_users
print(f"正常用户: {normal_users}")

# 找出VIP中的正常用户(VIP且未被封禁)
active_vip = vip_users & all_users - banned_users
print(f"活跃VIP: {active_vip}")

# 逐个处理
for user in active_vip:
    print(f"  给VIP用户 {user} 发福利!")

# 遍历两个集合的对称差
for user in all_users ^ vip_users:
    print(f"   {user} 不是VIP或者是VIP但不在此列表")

七、嵌套遍历

7.1 二维数据的遍历

# 遍历二维列表(矩阵)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

# 方式1:双层for循环
print("双层for循环:")
for row in matrix:
    for element in row:
        print(f"  {element}", end=' ')
    print()  # 换行

# 方式2:带索引的遍历
print("\n带坐标:")
for i, row in enumerate(matrix):
    for j, element in enumerate(row):
        print(f"  matrix[{i}][{j}] = {element}")

# 方式3:列表推导扁平化
flat = [element for row in matrix for element in row]
print(f"\n扁平化: {flat}")

# 方式4:计算每行每列的和
row_sums = [sum(row) for row in matrix]
col_sums = [sum(row[i] for row in matrix) for i in range(len(matrix[0]))]
print(f"行和: {row_sums}")
print(f"列和: {col_sums}")

7.2 多列表并行遍历 (zip)

# zip() 并行遍历多个序列
names = ["张三", "李四", "王五", "赵六"]
ages = [25, 30, 28, 22]
cities = ["北京", "上海", "广州", "深圳"]

# 方式1:zip遍历
print("=== zip 并行遍历 ===")
for name, age, city in zip(names, ages, cities):
    print(f"  {name}, {age}岁, {city}")

# 方式2:zip + enumerate
print("\n=== zip + enumerate ===")
for i, (name, age, city) in enumerate(zip(names, ages, cities), 1):
    print(f"  {i}. {name} - {age}岁 - {city}")

# ⚠️ zip按最短序列截断
short = [1, 2]
long_list = [1, 2, 3, 4, 5]
for a, b in zip(short, long_list):
    print(f"  {a}, {b}")  # 只输出2对!

# 如果需要按最长序列,用itertools.zip_longest
from itertools import zip_longest
print("\n=== zip_longest ===")
for a, b in zip_longest(short, long_list, fillvalue=None):
    print(f"  {a}, {b}")

八、for-else语句

# for-else 和 while-else 语义相同
# else在循环正常结束(没有被break中断)时执行

# 经典用法:搜索
def find_user(users, target_name):
    for user in users:
        if user["name"] == target_name:
            print(f"找到用户: {user}")
            break
    else:
        print(f"没有找到名为 {target_name} 的用户")
        return None
    return user

users = [
    {"name": "张三", "age": 25},
    {"name": "李四", "age": 30},
    {"name": "王五", "age": 28},
]

find_user(users, "李四")     # 找到
find_user(users, "赵六")     # 没找到

# 另一个例子:验证所有元素
def all_positive(numbers):
    for n in numbers:
        if n <= 0:
            print(f"发现非正数: {n}")
            break
    else:
        print("所有数字都是正数")
        return True
    return False

print(all_positive([1, 2, 3, 4, 5]))   # True
print(all_positive([1, -2, 3, 4]))     # False

九、实战案例

9.1 学生成绩分析系统

class ScoreAnalyzer:
    """学生成绩分析 —— for循环遍历各种数据结构"""
    
    def __init__(self, scores):
        """
        scores格式: {
            "张三": {"语文": 85, "数学": 92, "英语": 78},
            "李四": {"语文": 90, "数学": 88, "英语": 95},
            ...
        }
        """
        self.scores = scores
    
    def get_student_average(self):
        """计算每个学生的平均分"""
        result = {}
        for name, subjects in self.scores.items():
            if subjects:
                avg = sum(subjects.values()) / len(subjects)
                result[name] = round(avg, 1)
        return result
    
    def get_subject_average(self):
        """计算每个科目的平均分"""
        # 收集每个科目的所有分数
        subject_scores = {}
        for name, subjects in self.scores.items():
            for subject, score in subjects.items():
                if subject not in subject_scores:
                    subject_scores[subject] = []
                subject_scores[subject].append(score)
        
        # 计算平均
        result = {}
        for subject, scores in subject_scores.items():
            result[subject] = round(sum(scores) / len(scores), 1)
        return result
    
    def get_top_students(self, n=3):
        """获取总分前N名的学生"""
        totals = []
        for name, subjects in self.scores.items():
            total = sum(subjects.values())
            totals.append((name, total))
        
        # 按总分降序排列
        totals.sort(key=lambda x: x[1], reverse=True)
        return totals[:n]
    
    def get_failing_students(self, pass_score=60):
        """获取有不及格科目的学生"""
        failing = set()
        for name, subjects in self.scores.items():
            for subject, score in subjects.items():
                if score < pass_score:
                    failing.add(name)
                    break
        return failing
    
    def generate_report(self):
        """生成成绩报告"""
        print("=" * 50)
        print("📊 成绩分析报告")
        print("=" * 50)
        
        # 学生平均分
        print("\n📝 学生平均分:")
        for name, avg in self.get_student_average().items():
            bar = "█" * int(avg / 5)
            print(f"  {name:6} {avg:5.1f} {bar}")
        
        # 科目平均分
        print("\n📚 科目平均分:")
        for subject, avg in self.get_subject_average().items():
            print(f"  {subject}: {avg}")
        
        # 前3名
        print("\n🏆 总分前三:")
        for i, (name, total) in enumerate(self.get_top_students(3), 1):
            print(f"  {i}. {name}: {total}分")
        
        # 不及格学生
        failing = self.get_failing_students()
        if failing:
            print(f"\n⚠️ 有不及格科目的学生: {', '.join(failing)}")
        else:
            print(f"\n✅ 所有学生全部及格!")

# 测试数据
scores = {
    "张三": {"语文": 85, "数学": 92, "英语": 78, "物理": 88},
    "李四": {"语文": 90, "数学": 58, "英语": 95, "物理": 72},
    "王五": {"语文": 76, "数学": 85, "英语": 82, "物理": 90},
    "赵六": {"语文": 55, "数学": 72, "英语": 68, "物理": 45},
    "钱七": {"语文": 92, "数学": 95, "英语": 90, "物理": 88},
}

analyzer = ScoreAnalyzer(scores)
analyzer.generate_report()

9.2 购物车结算系统

class ShoppingCart:
    """购物车 —— for循环遍历的综合应用"""
    
    def __init__(self):
        self.items = []  # [(name, price, quantity), ...]
    
    def add_item(self, name, price, quantity=1):
        # 检查是否已存在
        for i, (item_name, item_price, item_qty) in enumerate(self.items):
            if item_name == name:
                self.items[i] = (item_name, item_price, item_qty + quantity)
                return
        self.items.append((name, price, quantity))
    
    def remove_item(self, name):
        self.items = [(n, p, q) for n, p, q in self.items if n != name]
    
    def total_price(self):
        return sum(price * qty for _, price, qty in self.items)
    
    def item_count(self):
        return sum(qty for _, _, qty in self.items)
    
    def print_receipt(self):
        """打印小票"""
        print("=" * 45)
        print("🛒 购物清单")
        print("=" * 45)
        print(f"{'商品':<20} {'单价':>8} {'数量':>6} {'小计':>8}")
        print("-" * 45)
        
        for name, price, quantity in self.items:
            subtotal = price * quantity
            print(f"{name:<20} ¥{price:>7.2f} {quantity:>6} ¥{subtotal:>7.2f}")
        
        print("-" * 45)
        total = self.total_price()
        count = self.item_count()
        print(f"{'合计':<20} {'':>8} {count:>6}件 ¥{total:>7.2f}")
        print("=" * 45)

# 使用
cart = ShoppingCart()
cart.add_item("Python编程书", 79.00, 2)
cart.add_item("机械键盘", 299.00, 1)
cart.add_item("鼠标垫", 29.90, 3)
cart.add_item("USB集线器", 49.00, 1)

cart.print_receipt()

十、本章小结

本文我们全面学习了Python for循环遍历各种数据结构:

  • 基本结构for 变量 in 可迭代对象:,底层基于迭代器协议。
  • 遍历列表:直接遍历、enumerate带索引遍历、遍历副本修改原列表。
  • 遍历元组:和列表类似,但天然安全(不可修改)。元组的解包遍历非常强大。
  • 遍历字典:三种方式——for key in dict(键)、for value in dict.values()(值)、for k, v in dict.items()(键值对)。items()解包遍历最常用。
  • 遍历集合:无序遍历,需要有序时用sorted()。配合集合运算做筛选非常高效。
  • 嵌套遍历:双层for遍历二维数据、zip并行遍历多序列、zip_longest按最长序列遍历。
  • for-else:和while-else语义一致——循环正常结束时执行else,被break中断时不执行。

for循环是Python中使用频率最高的循环结构。掌握它遍历各种数据类型的技巧,是写好Python代码的基础功。⌨️ 下一篇文章,我们将学习for-else循环的使用时机与注意点。

以上就是Python中for循环遍历列表元组字典集合的实用技巧的详细内容,更多关于Python for循环遍历的资料请关注脚本之家其它相关文章!

相关文章

  • Python初学时购物车程序练习实例(推荐)

    Python初学时购物车程序练习实例(推荐)

    下面小编就为大家带来一篇Python初学时购物车程序练习实例(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Python详细讲解浅拷贝与深拷贝的使用

    Python详细讲解浅拷贝与深拷贝的使用

    这篇文章主要介绍了Python中的深拷贝和浅拷贝,通过讲解Python中的浅拷贝和深拷贝的概念和背后的原理展开全文,需要的小伙伴可以参考一下
    2022-07-07
  • PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?

    PyCharm vs VSCode,作为python开发者,你更倾向哪种IDE呢?

    这篇文章主要介绍了PyCharm和vscode作为python ide的优劣,帮助你选择适合自己的ide,感兴趣的朋友可以了解下
    2020-08-08
  • python addict的基本用法示例详解

    python addict的基本用法示例详解

    addict 是一个流行的 Python 第三方库,主要用来让你像访问属性一样访问字典里的数据(即点操作符访问属性,而不是方括号),从而使字典操作更方便和美观,这篇文章给大家介绍python addict的用法,感兴趣的朋友跟随小编一起看看吧
    2026-02-02
  • Python实现一个Git日志统计分析的小工具

    Python实现一个Git日志统计分析的小工具

    这篇文章主要给大家介绍了关于利用Python如何实现一个Git日志统计分析小工具的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • python创建学生成绩管理系统

    python创建学生成绩管理系统

    这篇文章主要为大家详细介绍了python创建学生成绩管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Python字符编码转码之GBK,UTF8互转

    Python字符编码转码之GBK,UTF8互转

    说到python的编码,一句话总结,说多了都是泪啊,这个在以后的python的开发中绝对是一件令人头疼的事情。所以有必要输入理解
    2020-02-02
  • python 实现二维数组的索引、删除、拼接操作

    python 实现二维数组的索引、删除、拼接操作

    这篇文章主要介绍了python 实现二维数组的索引、删除、拼接操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • python构建自定义回调函数详解

    python构建自定义回调函数详解

    在工作中,回调函数使用的场景是非常多的,下面我们就来通过例子程序来详细了解利用了Python的属性机制构建了一个自定义回调函数的使用
    2017-06-06
  • python实现跨excel sheet复制代码实例

    python实现跨excel sheet复制代码实例

    这篇文章主要介绍了python实现跨excel sheet复制代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论