内卷地狱

9021_TUT_3 第 25 次课练习题

Edit Me

练习 1

题目描述

给定两个整数 mn,其中:

  • m 表示重复单元(pattern)的数量。
  • n 表示每个单元中元素(下划线)的数量。

目标是生成一个字符串,规则如下:

  • 每个单元包含 n 个下划线(_),以 | 分隔。
  • 各单元之间以 * 连接。

我的解法

def generate_struct(n):
    return '|'.join(n * ['_'])

def f1(m, n):
    return ' * '.join(m * [generate_struct(n)])

思路

我将每个单元视为独立的结构。先构建最小单元(用 | 连接下划线),再用 join()* 拼接各单元。

辅助函数 generate_struct(n)

生成基础结构:将 n 个下划线以 | 连接。
例如 n = 2 时,结果为 "_|_"

标准解法

def f1(m, n):
    return ' * '.join('|'.join('_' for _ in range(n)) for _ in range(m))

简洁表达

内层 join 用生成器表达式创建 n 个下划线以 | 连接的字符串;外层 join 重复 m 次,用 * 连接各单元。

两种方案的对比:我的解法注重模块化(拆分为小函数),标准解法将一切压缩为一行列表推导式。

练习 2

题目描述

根据给定数字 n 的各位数字生成图案:

  • 奇数位显示黑色方块(⬛)。
  • 偶数位显示白色方块(⬜)。

我的解法

def f2(n):
    ans = ''
    for i in str(n):
        if int(i) % 2 == 0:
            ans += '⬜'
        else:
            ans += '⬛'
    print(ans)

思路

  1. 将数字 n 转为字符串,逐位遍历。
  2. 用取模运算(% 2)判断奇偶。
  3. 奇数位追加黑色方块,偶数位追加白色方块。
  4. 打印最终字符串。

标准解法

def f2(n):
    print(''.join({0: '\u2b1c', 1: '\u2b1b'}[int(d) % 2] for d in str(n)))

Martin 博士的解法更 Pythonic:用字典和生成器表达式简化代码,Unicode 转义序列直接引用方块符号。

练习 3

题目描述

将数字 n 视为不同进制(2 到 10)下的表示,将其转换为十进制值(仅对合法进制有效)。

例如 n = 2143

  • 2143 在 5 进制下等于十进制的 298
  • 2143 在 6 进制下等于十进制的 495
  • 以此类推。

我的解法

def f3(n: int):
    for i in range(2, 11):
        try:
            value = int(str(n), i)
            print(f'{n} is {value} in base {i}')
        except ValueError:
            pass

思路

  1. 遍历进制 2 到 10。
  2. int(str(n), i)n 作为 i 进制数转换为十进制。若数字不合法则抛出 ValueError,跳过该进制。
  3. try-except 处理非法进制。

标准解法

def f3(n):
    n_as_string = str(n)
    min_base = max(2, max({int(d) for d in n_as_string}) + 1)
    for b in range(min_base, 11):
        print(f'{n} is {int(n_as_string, b)} in base {b}')

标准解法通过集合推导提取最大数字来确定最小合法进制,跳过非法进制而无需异常处理。

练习 4

题目描述

创建函数 f4(n, base),返回字典 D

  • 键为 0n 的整数。
  • 值为以 base 进制表示的元组(从十进制转换而来)。

我的解法

def convert_to_base(n, base):
    if n == 0:
        return '0'
    digits = []
    while n:
        digits.append(str(n % base))
        n //= base
    return ''.join(digits[::-1])

def f4(n: int, base: int):
    D = {}
    for i in range(0, n + 1):
        D[i] = tuple(map(int, convert_to_base(i, base)))
    return D

思路

  1. 辅助函数 convert_to_base(n, base) 用辗转相除法将十进制数转换为指定进制字符串。
  2. 主函数遍历 0n,转换每个数并存为元组。

关于 map() 的 Pythonic 性

map() 来自函数式编程范式,现在通常用列表推导式代替,因为后者更简洁、易读:

D[i] = tuple([int(digit) for digit in convert_to_base(i, base)])

标准解法

def f4(n, base):
    D = {0: (0,)}
    for m in range(1, n + 1):
        digits = []
        p = m
        while p:
            digits.append(p % base)
            p //= base
        D[m] = tuple(reversed(digits))
    return D

两种解法均正确。我的解法用辅助函数增加了模块化,标准解法更简洁,直接在主函数中完成转换。

练习 5

先运行这段代码:

print(0.1 + 0.2)

结果不是 0.3,而是 0.30000000000000004,这是为什么?

题目描述

此练习旨在揭示计算机浮点运算的局限性。计算机以二进制格式存储浮点数,通常会引入精度误差。

解法

def f5(integral_part, fractional_part):
    precision = len(str(fractional_part))
    a_float = float(str(integral_part) + '.' + str(fractional_part))
    simple_precision = f'{a_float:.{precision}f}'
    extended_simple_precision = simple_precision + '0' * precision
    double_precision = f'{a_float:.{precision * 2}f}'
    print('With', precision * 2, 'digits after the decimal point, ', end='')
    if extended_simple_precision == double_precision:
        print(simple_precision, 'prints out with', precision, 'trailing',
              precision == 1 and 'zero,' or 'zeroes,', 'namely, as',
              extended_simple_precision
             )
    else:
        print(simple_precision, 'prints out as', double_precision)

通过简单精度(simple_precision)和双精度(double_precision)对比,展示浮点数并非总是以我们期望的方式存储。

练习 6

题目描述

给定:

  • 列表 L,包含多个等长度 n 的整数子列表。
  • 列表 fields,是 {1, ..., n} 的一个排列。

要求用多键排序机制对 L 排序:先按 fields[0] 指定位置排序,相等时按 fields[1],以此类推。

例如 fields = [2, 1] 表示先按第二个元素排序,相同时按第一个元素排序。

我的解法

def f6(L, fields):
    return sorted(L, key=lambda x: [x[i-1] for i in fields])

sorted() 函数根据 key 排序。lambda 函数按 fields 中指定的位置提取每个子列表的元素,x[i-1] 是因为 fields 从 1 开始索引,而 Python 列表从 0 开始。

标准解法

def f6(L, fields):
    return sorted(L, key=lambda x: tuple(x[i - 1] for i in fields))

为什么用元组? 元组不可变,Python 内置排序可以高效比较元组。两种解法均正确,标准解法用元组更符合 Python 惯例。


贡献者


这篇文章有帮助吗?

最近更新

Involution Hell© 2026 byCommunityunderCC BY-NC-SA 4.0CCBYNCSA