Python: 字符串与容器综合

前几课我们把列表、元组、字典、集合、字符串的方法都学了。这一课把它们串起来——用几个最常见的"组合拳"解决实际问题。这些技巧在工作中天天用到。


1. split() 与列表的配合

split() 把字符串拆成列表,是数据处理的第一步:

PYTHON
# CSV 格式数据解析
line = "Alice,25,北京,工程师"
fields = line.split(",")
print(fields)               # ['Alice', '25', '北京', '工程师']

# 按空白分割(默认)
text = "hello   world    python"
words = text.split()
print(words)                # ['hello', 'world', 'python']

# 限制分割次数——只分割前 N 个
data = "2026-06-23-15-30-00"
parts = data.split("-", 3)
print(parts)                # ['2026', '06', '23', '15-30-00']

▶ 示例:解析配置文件(难度⭐⭐)

PYTHON
# 模拟解析配置文件
config_text = """
host=localhost
port=8080
debug=true
theme=dark
"""

# 按行分割 → 按等号分割 → 存入字典
config = {}
for line in config_text.strip().split("\n"):
    if "=" in line:
        key, value = line.split("=", 1)
        config[key.strip()] = value.strip()

print(config)
# {'host': 'localhost', 'port': '8080', 'debug': 'true', 'theme': 'dark'}

# 读取配置
print(f"当前主机:{config.get('host', 'localhost')}")
print(f"当前端口:{config.get('port', '80')}")
▶ 试一试

运行结果:

TEXT 📖 仅展示
{'host': 'localhost', 'port': '8080', 'debug': 'true', 'theme': 'dark'}
当前主机:localhost
当前端口:8080


2. join() 的妙用

join()split() 的反操作——把列表合并成字符串:

PYTHON
# 基本用法
words = ["Hello", "World", "Python"]
sentence = " ".join(words)
print(sentence)             # Hello World Python

# 用逗号连接
csv = ",".join(["Alice", "25", "北京"])
print(csv)                  # Alice,25,北京

# 用换行符连接
lines = "\n".join(["第一行", "第二行", "第三行"])
print(lines)

(1) join() 的性能优势

PYTHON
# ❌ 不推荐——循环拼接字符串
result = ""
for i in range(1000):
    result += str(i) + ","
# 这样会创建 1000 个临时字符串对象(字符串不可变)

# ✅ 推荐——用列表收集 + join()
parts = [str(i) for i in range(1000)]
result = ",".join(parts)
# 一次合并,效率高得多

▶ 示例:格式化输出表格(难度⭐⭐)

PYTHON
# 用 join + 列表推导式输出格式化表格
headers = ["姓名", "年龄", "城市"]
rows = [
    ["Alice", "25", "北京"],
    ["Bob", "30", "上海"],
    ["Charlie", "22", "广州"],
]

# 表头
print(" | ".join(headers))
print("-" * 25)

# 数据行
for row in rows:
    print(" | ".join(row))
▶ 试一试

运行结果:

TEXT 📖 仅展示
姓名 | 年龄 | 城市
─────────────────────────
Alice | 25 | 北京
Bob | 30 | 上海
Charlie | 22 | 广州


3. sorted() 对字符串和字典排序

sorted() 可以对任何可迭代对象排序,不只是列表:

PYTHON
# 对字符串排序——按字母顺序
text = "python"
sorted_chars = sorted(text)
print(sorted_chars)                 # ['h', 'n', 'o', 'p', 't', 'y']
print("".join(sorted_chars))        # hnopty——重新组合

# 对字典排序——默认按键排序
d = {"banana": 3, "apple": 5, "cherry": 2}
sorted_keys = sorted(d)
print(sorted_keys)                  # ['apple', 'banana', 'cherry']

# 按值排序
sorted_by_value = sorted(d.items(), key=lambda x: x[1])
print(sorted_by_value)              # [('cherry', 2), ('banana', 3), ('apple', 5)]

# 对集合排序
s = {3, 1, 4, 1, 5, 9}
sorted_set = sorted(s)
print(sorted_set)                   # [1, 3, 4, 5, 9]

▶ 示例:按自定义规则排序(难度⭐⭐)

PYTHON
# 对文件名排序——按数字部分
files = ["file_10.txt", "file_2.txt", "file_1.txt", "file_20.txt"]

# 普通排序——字符串排序,10 会排在 2 前面(因为 '1' < '2')
print(sorted(files))
# ['file_1.txt', 'file_10.txt', 'file_2.txt', 'file_20.txt']

# 按数字部分排序——提取数字转成 int 再排序
def extract_number(filename):
    num_str = filename.split("_")[1].split(".")[0]
    return int(num_str)

sorted_files = sorted(files, key=extract_number)
print(sorted_files)
# ['file_1.txt', 'file_2.txt', 'file_10.txt', 'file_20.txt']
▶ 试一试

输出:

TEXT 📖 仅展示
# 函数定义成功


4. enumerate() 与 zip()

这两个内置函数在工作中出现频率极高。

(1) enumerate() —— 遍历时获取索引

PYTHON
fruits = ["苹果", "香蕉", "橘子"]

# 不用 enumerate——麻烦
for i in range(len(fruits)):
    print(f"{i + 1}. {fruits[i]}")

# 用 enumerate——优雅
for i, fruit in enumerate(fruits, 1):    # start=1 从 1 开始计数
    print(f"{i}. {fruit}")

(2) zip() —— 并行遍历多个列表

PYTHON
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
cities = ["北京", "上海", "广州"]

# 同时遍历三个列表
for name, score, city in zip(names, scores, cities):
    print(f"{name}:{score}分,来自{city}")

运行结果:

TEXT 📖 仅展示
Alice:85分,来自北京
Bob:92分,来自上海
Charlie:78分,来自广州

▶ 示例:学生成绩报告(难度⭐⭐⭐)

PYTHON
# 用 enumerate + zip 生成完整成绩单
students = ["Alice", "Bob", "Charlie", "赵六"]
chinese = [85, 92, 78, 88]
math = [90, 85, 95, 80]
english = [78, 95, 82, 90]

print("=== 学生成绩报告 ===")
print(f"{'排名':<4}{'姓名':<6}{'语文':<6}{'数学':<6}{'英语':<6}{'平均分':<6}")

# 计算平均分
averages = [(c + m + e) / 3 for c, m, e in zip(chinese, math, english)]

# 按平均分降序排序
data = list(zip(students, chinese, math, english, averages))
data.sort(key=lambda x: x[4], reverse=True)

# 输出
for rank, (name, c, m, e, avg) in enumerate(data, 1):
    print(f"{rank:<4}{name:<6}{c:<6}{m:<6}{e:<6}{avg:<6.1f}")
▶ 试一试

运行结果:

TEXT 📖 仅展示
=== 学生成绩报告 ===
排名  姓名  语文  数学  英语  平均分
1    Bob  92   85   95   90.7
2    Alice  85   90   78   84.3
3    Charlie  78   95   82   85.0
4    赵六  88   80   90   86.0


5. 综合数据处理案例

把今天学的所有技巧用在一个实际场景中:

(1) 案例:日志分析(难度⭐⭐⭐)

PYTHON
# 模拟服务器日志
log_data = """
2026-06-20 10:23:45 INFO  用户 1001 登录成功
2026-06-20 10:25:12 ERROR 数据库连接超时
2026-06-20 10:26:30 INFO  用户 1002 登录成功
2026-06-20 10:27:45 WARN  磁盘使用率 85%
2026-06-20 10:28:10 ERROR 用户 1001 请求超时
2026-06-20 10:29:00 INFO  用户 1001 登出
"""

# 1. 按行分割
lines = log_data.strip().split("\n")

# 2. 解析每条日志
parsed = []
for line in lines:
    parts = line.split()
    timestamp = f"{parts[0]} {parts[1]}"
    level = parts[2]
    message = " ".join(parts[3:])
    parsed.append({"time": timestamp, "level": level, "msg": message})

# 3. 统计各等级数量
level_count = {}
for entry in parsed:
    level = entry["level"]
    level_count[level] = level_count.get(level, 0) + 1

# 4. 按等级排序输出
print("=== 日志统计 ===")
for level, count in sorted(level_count.items()):
    print(f"{level}: {count} 条")

# 5. 筛选出所有 ERROR
print("\n=== 错误详情 ===")
errors = [e for e in parsed if e["level"] == "ERROR"]
for e in errors:
    print(f"[{e['time']}] {e['msg']}")

运行结果:

TEXT 📖 仅展示
=== 日志统计 ===
ERROR: 2 条
INFO: 3 条
WARN: 1 条

=== 错误详情 ===
[2026-06-20 10:25:12] 数据库连接超时
[2026-06-20 10:28:10] 用户 1001 请求超时


6. 常见应用场景


❓ 常见问题

Q split()split(" ") 有什么区别?
A split() 不加参数时,会按任意空白字符(空格、换行、制表符)分割,并且自动去掉空字符串。split(" ") 只按单个空格分割,连续的空格会产生空字符串。大多数时候用不带参数的 split() 更合适。
Q join() 要求列表中的所有元素都是字符串吗?
A 是的。如果列表中有数字,",".join([1, 2, 3]) 会报错。需要先把数字转成字符串:",".join(str(x) for x in [1, 2, 3])。或者在列表推导式里用 str() 转换。
Q zip() 处理不等长的列表会怎样?
A zip() 会在最短的列表结束时停止。如果三个列表中有一个只有 2 个元素,zip() 只产生 2 对。如果你希望按最长的来(不足的补 None),用 itertools.zip_longest()

📖 小节


📝 作业

  1. 基础题(难度⭐):给定字符串 s = "apple,banana,orange,grape",用 split() 拆成列表,用 join() 合并成 "apple | banana | orange | grape" 格式输出。

  2. 进阶题(难度⭐⭐):给定两个列表 students = ["Alice", "Bob", "Charlie"]scores = [85, 92, 78],用 zip()enumerate() 输出带排名的成绩单:

    TEXT 📖 仅展示
    第1名:Bob —— 92分
    第2名:Alice —— 85分
    第3名:Charlie —— 78分
    
  3. 挑战题(难度⭐⭐⭐):写一个"简易 CSV 生成器"。给定一个列表的列表 data = [["姓名", "年龄", "城市"], ["Alice", 25, "北京"], ["Bob", 30, "上海"]],将其输出为 CSV 格式的字符串(每行用逗号分隔,数字自动转字符串)。提示:列表推导式里用 str() 转数字,用 ",".join() 拼行,用 "\n".join() 拼所有行。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏