Python基础数据类型练习题:数字、字符串与列表经典例题解析

Felix
Felix
发布时间:2026-11-14 | 6人浏览过
原创

针对Python初学者在数字、字符串与列表三种核心数据类型中的经典练习题进行详细解析,包含类型转换、字符串清洗回文判断、列表去重与切片变形等典型场景。

在学习 Python 的过程中,数字(int、float)、字符串(str)与列表(list)构成了程序逻辑处理的基石。很多初学者在分别看懂语法规则后,面对实际代码编写仍然会感到无从下手。本文通过精选的几个典型练习题,围绕数值精度与进制转换、字符串清洗与回文判定、列表统计与原地去重等核心操作,逐题解析解题思路、代码实现及常见陷阱,帮助读者切实巩固对基础数据类型的理解与运用能力。

一、数字类型练习:精度控制与进制转换

Python 中的数字主要包括整数(int)与浮点数(float)。由于计算机内部采用二进制表示小数,浮点数运算常常伴随着精度舍入问题;而在不同系统交互或底层数据解析时,进制转换也是极为基础的能力。

例题 1:商品折扣与货币四舍五入计算

题目要求:给定一件商品的原价(如 199.9 元)和折扣率(如 0.85),计算折后价格,并严格保留两位小数输出。要求处理类似 0.1 + 0.2 带来的浮点精度不准确现象。

# 示例代码:商品折后价计算
from decimal import Decimal, ROUND_HALF_UP

original_price = "199.9"
discount = "0.85"

# 使用 Decimal 避免浮点数存储误差
price_dec = Decimal(original_price)
discount_dec = Decimal(discount)
total = price_dec * discount_dec

# 严格执行四舍五入到两位小数
final_price = total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
print(f"原价: {original_price},折后价: {final_price}")

# 示例输出:
# 原价: 199.9,折后价: 169.92

避坑提示:Python 内置的 round() 函数采用“奇进偶舍”(Banker's rounding)规则,并非传统数学上的四舍五入。涉及货币等敏感计算时,建议传入字符串构造 Decimal,并指定 ROUND_HALF_UP。

例题 2:十进制转二进制、八进制与十六进制

题目要求:输入一个正整数,输出其对应的无前缀二进制、八进制及大写十六进制字符串。

# 示例代码:格式化进制转换
num = 254

# 使用内置 format 函数,指定格式符 'b'、'o'、'X'
bin_str = format(num, 'b')
oct_str = format(num, 'o')
hex_str = format(num, 'X')

print(f"十进制: {num}")
print(f"二进制: {bin_str}")
print(f"八进制: {oct_str}")
print(f"十六进制: {hex_str}")

# 示例输出:
# 十进制: 254
# 二进制: 11111110
# 八进制: 376
# 十六进制: FE
Python基础数据类型练习题:数字、字符串与列表经典例题解析
图 1: 高精度数值处理与舍入步骤规范

二、字符串类型练习:文本清洗与结构判定

字符串在 Python 中是不可变序列(immutable sequence)。无论对字符串执行何种替换、拼接或切片,原字符串都不会改变,而是返回一个全新的字符串对象。常见练习题通常考查对字符遍历、条件过滤和切片步长机制的熟练度。

例题 3:有效回文字符串检验

题目要求:给定一个可能包含大小写字母、数字、空格及标点符号的字符串,忽略所有非字母数字字符且忽略大小写,判断其是否为回文字符串(正读与反读完全一致)。

# 示例代码:双向验证回文字符串
def is_valid_palindrome(text: str) -> bool:
    # 步骤 1: 过滤字符并统一转为小写
    cleaned_chars = [ch.lower() for ch in text if ch.isalnum()]
    
    # 步骤 2: 重新组装字符串
    cleaned_text = "".join(cleaned_chars)
    
    # 步骤 3: 利用切片步长 [::-1] 反转并对比
    return cleaned_text == cleaned_text[::-1]

test_cases = [
    "A man, a plan, a canal: Panama",
    "race a car",
    "No lemon, no melon"
]

for item in test_cases:
    result = is_valid_palindrome(item)
    print(f"原句: \"{item}\" -> 回文判定: {result}")

# 示例输出:
# 原句: "A man, a plan, a canal: Panama" -> 回文判定: True
# 原句: "race a car" -> 回文判定: False
# 原句: "No lemon, no melon" -> 回文判定: True
Python基础数据类型练习题:数字、字符串与列表经典例题解析
图 2: 字符串回文校验的切片与双指针实现差异

例题 4:词频统计与标点清洗

题目要求:统计一段英文段落中每个单词出现的次数,要求忽略大小写,并去除单词周围的标点符号(如句号、逗号、感叹号)。

# 示例代码:基础词频统计
import string

paragraph = "Python is powerful, and Python is easy to learn! Is it true?"

# 移除标点并转为小写
clean_text = paragraph.lower()
for p in string.punctuation:
    clean_text = clean_text.replace(p, " ")

# 拆分为单词列表
words = clean_text.split()

# 统计词频
word_count = {}
for word in words:
    word_count[word] = word_count.get(word, 0) + 1

# 按出现频次倒序排列
sorted_words = sorted(word_count.items(), key=lambda item: item[1], reverse=True)
for w, count in sorted_words:
    print(f"{w}: {count}")

# 示例输出:
# python: 2
# is: 3
# powerful: 1
# and: 1
# easy: 1
# to: 1
# learn: 1
# it: 1
# true: 1

三、列表类型练习:切片、变异与有序去重

与字符串不同,列表(list)是可变序列(mutable sequence)。你可以随时向列表追加元素、删除指定项或原地排序。初学者的经典痛点主要集中在:在循环遍历列表的同时修改列表元素导致索引错位,以及如何保持元素原有顺序进行去重。

例题 5:保持顺序的列表去重

题目要求:给定一个包含重复元素的列表,移除所有重复项,并且保留元素首次出现的先后次序。

# 示例代码:保序去重方案
raw_list = [3, 1, 2, 3, 4, 1, 5, 2, 6, 4]

# 方法一:利用 Python 3.7+ 字典键有序特性(简洁高效)
unique_ordered_dict = list(dict.fromkeys(raw_list))

# 方法二:集合辅助遍历(逻辑通用)
seen = set()
unique_ordered_loop = []
for item in raw_list:
    if item not in seen:
        seen.add(item)
        unique_ordered_loop.append(item)

print(f"原列表: {raw_list}")
print(f"去重后(字典法): {unique_ordered_dict}")
print(f"去重后(循环法): {unique_ordered_loop}")

# 示例输出:
# 原列表: [3, 1, 2, 3, 4, 1, 5, 2, 6, 4]
# 去重后(字典法): [3, 1, 2, 4, 5, 6]
# 去重后(循环法): [3, 1, 2, 4, 5, 6]

避坑提示:许多初学者直接使用 list(set(raw_list)),虽然成功去除了重复值,但由于集合(set)本身是无序哈希表,原有元素的相对次序被打乱。因此需要有序去重时,请使用上述两种方案。

例题 6:滑动窗口均值计算(列表切片进阶)

题目要求:给定一个数值列表和一个固定窗口大小 k,计算每个连续窗口内数字的平均值,返回新的平均值列表。

# 示例代码:滑动窗口计算
def moving_average(data: list, k: int) -> list:
    if not data or k <= 0 or k > len(data):
        return []
    
    averages = []
    # 窗口起点从 0 遍历到 len(data) - k
    for i in range(len(data) - k + 1):
        window = data[i:i + k]
        window_avg = sum(window) / k
        averages.append(round(window_avg, 2))
    return averages

scores = [10, 20, 30, 40, 50, 60, 70]
window_size = 3
result = moving_average(scores, window_size)

print(f"原始数据: {scores}")
print(f"窗口大小: {window_size}")
print(f"滑动均值: {result}")

# 示例输出:
# 原始数据: [10, 20, 30, 40, 50, 60, 70]
# 窗口大小: 3
# 滑动均值: [20.0, 30.0, 40.0, 50.0, 60.0]
Python基础数据类型练习题:数字、字符串与列表经典例题解析
图 3: 列表连续切片滑动窗口计算原理

四、三类数据特性对比与总结

综合以上例题,数字、字符串与列表在底层存储机制与操作行为上有本质区别。在实际开发中,需要根据不可变性(Immutability)、有序性(Order)以及时间复杂度选择合适的数据结构与处理手法。

Python基础数据类型练习题:数字、字符串与列表经典例题解析
图 4: 数字、字符串与列表核心特性与易错点横向对比

五、学习建议与常见问题答疑

  • 为什么不能在 for 循环遍历列表时直接 list.remove()?
    因为 remove() 会使列表长度即时发生变化,后续元素的索引向前平移,而 for 循环基于自增索引继续移动,这会导致紧邻被删元素后面的那一项被直接跳过。安全做法是使用列表推导式生成新列表,或者倒序遍历。
  • 字符串频次统计时,大量拼接 += 为何较慢?
    字符串具有不可变性,每次 += 都在内存中重新申请空间并拷贝所有旧字符,当字符串很长或循环次数很多时,时间复杂度会劣化为 \(O(N^2)\)。推荐先收集到列表中,最终使用 "".join(list) 一次性拼接。
  • 如何选择切片还是双指针?
    在竞赛或内存受限的大规模数据流场景下,双指针能够实现 \(O(1)\) 的额外空间占用;而在日常业务或简短脚本中,Python 原生切片 s[::-1] 执行效率极高且可读性最佳。
相关专题:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表