python学习之路☞10.for, while loop and range(), enumerate(), zip() funcation and continue, break and comprehension

python学习之路☞10.for, while loop and range(), enumerate(), zip() funcation and continue, break and comprehension

#python,#for,#while,#loop,#range(),#enumerate(),#zip(),#funcation,#continue,#break,#comprehension,

for 循环

'''
for 循环:顺序遍历迭代器(iterator)中的每个子项(item),
           并对每个子项执行语句块(block of statements)。

  迭代器(iterator):每次循环返回集合中的一个子项,
                      子项可以是任意类型。
                      常见的可迭代对象:list、str、tuple、range 等。

  语句块(block):由缩进对齐的多行语句组成,循环每次执行一遍。

  单循环                   嵌套循环
  ─────────────────────    ─────────────────────────────
  for item in iterator:    for item in iterator:
      pass                     for item in iterator:
                                   pass
'''

range()

'''
range(start, stop, step)
    ├── start : 起始值,默认 0(含)
    ├── stop  : 结束值(不含),左闭右开 [start, stop)
    └── step  : 步长,默认 1

  range(5)       → 0 1 2 3 4
  range(1, 6)    → 1 2 3 4 5
  range(1, 10, 2)→ 1 3 5 7 9(奇数)
  range(10, 0, -1)→ 10 9 8 … 1(倒序)
'''
print(range(1, 10, 2), type(range(1, 10, 2)))
print(list(range(1, 10, 2)))  # 转 list 才能看到所有值

for 基础练习

1) 奇数打印

print('\n--- 1) 单循环:奇数打印 ---')
for i in range(1, 10, 2):  # [1, 10) 步长 2 → 1 3 5 7 9
    print(i, end=' ')
print()  # 换行

2) 嵌套循环:5×5 方形

# 原始感悟:起初被 print() 自带换行困住,后来想到用 += 拼接字符串,
# 那种"无计可施到突然得解"的感动,让我真实地流泪了。
# 这说明:学会的基础知识,组合起来就能解决新问题。
print('\n--- 2) 嵌套循环:5×5 方形 ---')
for i in range(5):
    line = 'y '          # 每行行头标记
    for j in range(5):
        line += 'x '     # += 每次追加一列(等价于 line = line + 'x ')
    print(line)

3) 奇数平方和:1² + 3² + 5² + 7² + 9²

print('\n--- 3) 奇数平方和 ---')
expr = ''    # 记录算式字符串,方便打印过程
total = 0    # 累加结果
for i in range(1, 10, 2):
    expr += f'{i}×{i}'
    if i < 9:
        expr += ' + '
    total += i * i
print(f'{expr} = {total}')

4) 9×9 乘法表

print('\n--- 4) 9×9 乘法表 ---')
for i in range(1, 10):          # 外循环控制行(1~9)
    line = ''
    for j in range(1, i + 1):  # 内循环控制列(1~i),形成下三角
        line += f'{i}×{j}={i*j} '
    print(line)

for 带函数调用练习

1) 计算 num1 到 num2 的整数和

def additions_sum(num1, num2):
    '''
    计算 num1 到 num2(含)的所有整数之和。

    :param num1: 起始整数
    :type num1: int
    :param num2: 结束整数
    :type num2: int
    :return: 范围内所有整数的和
    :rtype: int

    修复说明:原来用 sum 做变量名,会遮蔽 Python 内置函数 sum()。
             改为 total 避免冲突。
    '''
    total = 0                       # 不用 sum,避免覆盖内置函数
    for i in range(num1, num2 + 1):
        total += i
    return total
    # 一行版本(内置函数直接搞定):
    # return sum(range(num1, num2 + 1))

print('\n--- 1) 1 到 100 的整数和 ---')
print(additions_sum(1, 100))    # 高斯公式验证:5050

2) 返回 num1 到 num2 中所有偶数的列表

def print_even(num1, num2):
    '''
    返回 num1 到 num2(含)中所有偶数组成的列表。

    :param num1: 起始整数
    :type num1: int
    :param num2: 结束整数
    :type num2: int
    :return: 偶数列表
    :rtype: list
    '''
    even_list = []
    for i in range(num1, num2 + 1):
        if i % 2 == 0:
            even_list.append(i)
    return even_list
    # 列表推导式版本:
    # return [i for i in range(num1, num2 + 1) if i % 2 == 0]
print('\n--- 2) 1 到 100 的偶数 ---')
print(print_even(1, 100))

3) 找出同时被 3 和 5 整除的数

def divisible_3_5(num1, num2):
    '''
    返回 num1 到 num2(含)中能同时被 3 和 5 整除的数的列表。

    :param num1: 起始整数
    :type num1: int
    :param num2: 结束整数
    :type num2: int
    :return: 同时被 3 和 5 整除的数的列表
    :rtype: list

    修复说明:函数名由 floor_division_3_5 改为 divisible_3_5,
             更准确地描述"能整除"而非"做整除运算"。
    '''
    result = []
    for i in range(num1, num2 + 1):
        if i % 3 == 0 and i % 5 == 0:
            result.append(i)
    return result
    # 等价写法:i % 15 == 0(3 和 5 的最小公倍数)
print('\n--- 3) 1 到 100 中同时被 3 和 5 整除的数 ---')
print(divisible_3_5(1, 100))

4) 生成 num1 到 num2 的平方列表

def power_list(num1, num2):
    '''
    返回 num1 到 num2(含)每个整数的平方组成的列表。

    :param num1: 起始整数
    :type num1: int
    :param num2: 结束整数
    :type num2: int
    :return: 平方列表
    :rtype: list
    '''
    result = []
    for i in range(num1, num2 + 1):
        result.append(i ** 2)
    return result
    # 列表推导式版本:
    # return [i ** 2 for i in range(num1, num2 + 1)]
print('\n--- 4) 1 到 10 的平方列表 ---')
squares = power_list(1, 10)
print(squares)

5) 计算列表的平均值

def avg_value(num_list):
    '''
    计算列表中所有元素的平均值。

    :param num_list: 数字列表
    :type num_list: list
    :return: 平均值
    :rtype: float

    修复说明:原来用 sum 做变量名,会遮蔽内置函数 sum(),改为 total。
             遍历方式改为直接遍历元素(更 Pythonic),不再用 range(len(...))。
    '''
    total = 0
    for num in num_list:    # 直接遍历元素,不用 range(len())
        total += num
    return total / len(num_list)
    # 一行版本:
    # return sum(num_list) / len(num_list)
print('\n--- 5) 上面平方列表的平均值 ---')
print(avg_value(squares))

6) 遍历字符串,打印每个字符及其索引

def str_loop(str_iter):
    '''
    打印字符串中每个字符及其索引位置,演示两种写法。

    :param str_iter: 目标字符串
    :type str_iter: str
    '''
    print('  方式一:range(len(...))')
    for i in range(len(str_iter)):
        print(f'  [{i}] {str_iter[i]}')

    print('  方式二:enumerate()(推荐)')
    for i, ch in enumerate(str_iter):
        print(f'  [{i}] {ch}')
    # enumerate() 更简洁,且不需要手动索引,推荐优先使用
print('\n--- 6) 遍历字符串 ---')
str_loop('你好世界!')

7) 找出列表的最大值和最小值

def find_min_max(num_list):
    '''
    找出列表中的最小值和最大值,并打印比较过程。

    :param num_list: 数字列表
    :type num_list: list
    :return: (最小值, 最大值) 元组
    :rtype: tuple
    '''
    min_val = num_list[0]   # 先假设第一个是最小值
    max_val = num_list[0]   # 先假设第一个是最大值
    count = 0
    for val in num_list:
        count += 1
        if val < min_val:
            print(f'  新最小值: {min_val} → {val}')
            min_val = val
        if val > max_val:
            print(f'  新最大值: {max_val} → {val}')
            max_val = val
    print(f'  共比较 {count} 次 | 最小值 {min_val} | 最大值 {max_val}')
    return min_val, max_val
    # 内置函数版本:min(num_list), max(num_list)
print('\n--- 7) 找最大值和最小值 ---')
find_min_max([3, 2, 5, 6, 7, 9, 11, 0, 8, 10])

8) 斐波那契数列(迭代版,清晰易懂)

def fibonacci_iter(num):
    '''
    用迭代方式生成斐波那契数列的前 num 个数。
    数列规律:F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2)
    前10项:0, 1, 1, 2, 3, 5, 8, 13, 21, 34

    :param num: 生成个数
    :type num: int
    :return: 斐波那契数列列表
    :rtype: list
    '''
    if num <= 0:
        return []
    result = []
    a, b = 0, 1             # a=当前项,b=下一项
    for _ in range(num):    # _ 表示循环变量不使用
        result.append(a)
        a, b = b, a + b     # 同时更新:a 变成 b,b 变成 a+b
    return result
print('\n--- 8) 斐波那契(迭代)前 10 项 ---')
print(fibonacci_iter(10))

9) 斐波那契数列(递归版)

def fibonacci_recur(fn0=0, fn1=1, num=10, num_list=None):
    '''
    用递归方式生成斐波那契数列的前 num 个数。

    :param fn0: 当前项,默认 0
    :type fn0: int
    :param fn1: 下一项,默认 1
    :type fn1: int
    :param num: 剩余需要生成的个数,默认 10
    :type num: int
    :param num_list: 累积结果列表,默认 None
    :type num_list: list | None
    :return: 斐波那契数列列表
    :rtype: list

    修复说明:原来默认参数 num_list=[] 会导致多次调用时列表不断累积
             (Python 可变默认参数陷阱)。改为 None,在函数内部创建新列表。

    递归理解:
        每次调用把 fn0 追加到列表,然后以 fn1 为新的 fn0,
        以 fn0+fn1 为新的 fn1,继续递归,直到 num 减为 0。
    '''
    if num_list is None:        # 修复可变默认参数陷阱
        num_list = []
    if num == 0:
        return num_list
    num_list.append(fn0)
    return fibonacci_recur(fn1, fn0 + fn1, num - 1, num_list)
print('\n--- 9) 斐波那契(递归)前 11 项 ---')
print(fibonacci_recur(num=11))
# 验证可变默认参数已修复:连续调用两次结果应该相同
print(fibonacci_recur(num=5))   # 若未修复,这里会包含上次的残留数据

10) 展开嵌套列表(递归版)

def flatten_list(nested, result=None):
    '''
    递归展开任意深度的嵌套列表,返回一个一维列表。

    :param nested: 嵌套列表
    :type nested: list
    :param result: 累积结果列表,默认 None
    :type result: list | None
    :return: 展开后的一维列表
    :rtype: list

    修复说明:原来默认参数 new_lists=[] 有可变默认参数陷阱,改为 None。

    递归理解:
        遍历列表的每个元素:
          - 若元素是 list → 递归处理(继续展开)
          - 若元素不是 list → 直接追加到 result
        终止条件:当前层没有 list 类型的元素。
    '''
    if result is None:          # 修复可变默认参数陷阱
        result = []
    for item in nested:
        if isinstance(item, list):          # 用 isinstance() 替代 type()==list
            flatten_list(item, result)      # 递归展开子列表
        else:
            result.append(item)
    return result
print('\n--- 10) 展开嵌套列表 ---')
nested = [[4, 5, 6, [17, 18, 19]], [14, 15, 16], [11, 12, 13], [7, 8, 9], [1, 2, 3]]
print('原始:', nested)
print('展开:', flatten_list(nested))

11) 找出字符串中出现次数最多的字符

def find_most_freq(text):
    '''
    找出字符串中出现次数最多的字符(可能有多个并列)。

    :param text: 目标字符串
    :type text: str
    :return: (出现最多的字符列表, 最大次数) 元组
    :rtype: tuple[list, int]
    '''
    char_count = {}     # 字典:字符 → 出现次数
    top_chars = []      # 并列最多的字符列表
    max_count = 0       # 当前最大次数

    for ch in text:
        # 字典 get(key, default):key 不存在时返回 default,避免 KeyError
        char_count[ch] = char_count.get(ch, 0) + 1

        if char_count[ch] > max_count:
            max_count = char_count[ch]
            top_chars = [ch]            # 出现新的最大值,重置列表
        elif char_count[ch] == max_count:
            top_chars.append(ch)        # 并列最大,追加
    return top_chars, max_count
print('\n--- 11) 字符串中出现最多的字符 ---')
text = 'python学习之路,学习使我快乐,学无止境!'
chars, count = find_most_freq(text)
print(f'出现最多的字符:{chars},次数:{count}')

while 循环

'''
while 循环:条件为真时反复执行语句块,条件为假时退出。

  单循环                       嵌套循环
  ─────────────────────────    ─────────────────────────────
  while condition:             while condition:
      pass                         while condition:
                                       pass

 死循环风险:必须确保循环体内有能让条件变为 False 的操作,
      否则程序永远无法退出(死循环)。
      通常在循环体内对计数变量自增,或在满足条件时 break。

  while vs for:
    for  → 已知迭代次数或遍历固定集合时用
    while→ 次数不确定、依赖条件判断时用(如猜数字游戏、读取输入直到合法)
'''

while 基础练习

1) while 单循环:拼接 0~8

print('\n--- while 1) 单循环:拼接 0~8 ---')
i = 0
line = ''
while i < 9:
    line += str(i) + ' '
    i += 1              # 必须自增,否则死循环
print('结果:', line)

2) while 嵌套:乘法表

print('\n--- while 2) 嵌套循环:乘法表 ---')
i = 1
while i < 10:
    j = 1
    line = ''
    while j <= i:
        line += f'{i}×{j}={i*j}'
        if j < i:
            line += '  '
        j += 1
    i += 1
    print(line)

continue / break(for 和 while 通用)

'''
  continue:跳过本次循环剩余代码,直接进入下一次迭代。
  break   :立即终止整个循环,不再执行任何迭代。

  while condition:
      if skip_condition:
          continue        # 回到 while 判断
      if stop_condition:
          break           # 跳出 while
      pass
'''

3) while + continue:筛选奇数

print('\n--- while 3) continue:筛选奇数 ---')
i = 0
odd_str = ''
while i < 50:
    i += 1              # 先自增再判断,否则跳过 continue 时 i 不增,死循环
    if i % 2 == 0:
        continue        # 偶数直接跳过
    odd_str += str(i) + ' '
print('奇数:', odd_str)

4) while + break:猜数字游戏

print('\n--- while 4) break:猜数字游戏 ---')
TARGET = 5          # 目标数(实际项目会用 random.randint())
MIN_NUM = 1
MAX_NUM = 10
MAX_CHANCE = 5
chance = 0

print(f'猜一个 {MIN_NUM}~{MAX_NUM} 之间的整数,共 {MAX_CHANCE} 次机会')
while chance < MAX_CHANCE:
    chance += 1
    guess = int(input(f'第 {chance} 次猜:'))
    if guess > TARGET:
        print('  大了')
    elif guess < TARGET:
        print('  小了')
    else:
        print(f'  猜对了!共用 {chance} 次,使用 break 退出循环')
        break           # 猜对立即退出
    remaining = MAX_CHANCE - chance
    if remaining > 0:
        print(f'  还剩 {remaining} 次机会')
    else:
        print(f'  机会用完,答案是 {TARGET},你输了')

for/while 延伸知识

for/while 的 else 子句(Python 特有)

'''
循环正常结束(没有被 break 打断)时,执行 else 块。
常用场景:搜索失败时的默认处理。
'''
print('\n--- 延伸 1) for...else ---')
target = 7
for i in [1, 3, 5, 9]:
    if i == target:
        print(f'找到了 {target}')
        break
else:
    print(f'没有找到 {target}')   # break 未触发时执行

enumerate():同时获取索引和值(替代 range(len(…)))

print('\n--- 延伸 2) enumerate() ---')
fruits = ['苹果', '香蕉', '橙子']

# 旧写法:range(len(...)) 手动索引
for i in range(len(fruits)):
    print(f'  [{i}] {fruits[i]}')
  
# 推荐写法:enumerate() 更简洁
for i, fruit in enumerate(fruits):
    print(f'  [{i}] {fruit}')

# start 参数:指定起始索引(默认 0)
for i, fruit in enumerate(fruits, start=1):
    print(f'  {i}. {fruit}')

zip():同时遍历多个列表, zip 以最短列表为准,多余的元素会被忽略

print('\n--- 延伸 3) zip() ---')
names  = ['Alice', 'Bob', 'Carol']
scores = [90, 85, 92]
grades = ['A', 'B', 'A']

for name, score, grade in zip(names, scores, grades):
    print(f'  {name}: {score} 分 → {grade}')

列表推导式(Comprehension)

'''
语法:[expression for item in iterable if condition]
      ↑ 生成的值    ↑ 遍历来源              ↑ 可选过滤条件

本质:把"创建空列表 → for 循环 → append"三步合为一行。
优点:简洁、可读、速度比手动 append 稍快。
'''
print('\n--- 延伸 4) 列表推导式 ---')

# 偶数列表
evens = [i for i in range(1, 21) if i % 2 == 0]
print('偶数:', evens)

# 平方列表
squares = [i ** 2 for i in range(1, 11)]
print('平方:', squares)

# 字符串处理
words = ['  hello  ', '  world  ', '  python  ']
cleaned = [w.strip().upper() for w in words]
print('清理后:', cleaned)

# 嵌套推导式(展开二维列表)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print('展开矩阵:', flat)

参考

python-for-loop
range()
break-and-continue-statements
else-clauses-on-loops
enumerate())
zip())
set-comprehension
list-comprehension
dictionary-comprehension

Comments