Python04_序列和字符串
文章目录
- Python04_序列和字符串
- [Python 序列与字符串转化完全指南](#Python 序列与字符串转化完全指南)
-
- 一、序列基础概念
-
- [1.1 什么是序列(Sequence)](#1.1 什么是序列(Sequence))
- [1.2 序列的通用操作](#1.2 序列的通用操作)
- 二、字符串与列表的转化
-
- [2.1 字符串 → 列表](#2.1 字符串 → 列表)
-
- [方法1:list() 函数 - 拆分为单个字符](#方法1:list() 函数 - 拆分为单个字符)
- [方法2:split() 方法 - 按分隔符拆分](#方法2:split() 方法 - 按分隔符拆分)
- [方法3:splitlines() - 按行拆分](#方法3:splitlines() - 按行拆分)
- [2.2 列表 → 字符串](#2.2 列表 → 字符串)
-
- [方法:join() 方法](#方法:join() 方法)
- [2.3 综合案例:字符串处理流水线](#2.3 综合案例:字符串处理流水线)
- 三、字符串与元组的转化
-
- [3.1 字符串 → 元组](#3.1 字符串 → 元组)
- [3.2 元组 → 字符串](#3.2 元组 → 字符串)
- [3.3 为什么需要元组?](#3.3 为什么需要元组?)
- 四、序列间的相互转化
-
- [4.1 转化关系图](#4.1 转化关系图)
- [4.2 列表与元组的转化](#4.2 列表与元组的转化)
- [4.3 序列与集合的转化](#4.3 序列与集合的转化)
- [4.4 序列与字典的转化](#4.4 序列与字典的转化)
- 五、编码与解码转化
-
- [5.1 字符串与字节的本质区别](#5.1 字符串与字节的本质区别)
- [5.2 编码:字符串 → 字节](#5.2 编码:字符串 → 字节)
- [5.3 解码:字节 → 字符串](#5.3 解码:字节 → 字符串)
- [5.4 常见编码错误](#5.4 常见编码错误)
- 六、格式化字符串与序列
-
- [6.1 序列数据格式化输出](#6.1 序列数据格式化输出)
- [6.2 序列对齐与填充](#6.2 序列对齐与填充)
- 七、常见问题与易错点
-
- [7.1 高频错误速查表](#7.1 高频错误速查表)
- [7.2 字符串修改的"曲线救国"](#7.2 字符串修改的"曲线救国")
- [7.3 性能优化建议](#7.3 性能优化建议)
- [7.4 面试常考代码片段](#7.4 面试常考代码片段)
- 附录:速查表
Python 序列与字符串转化完全指南
一、序列基础概念
1.1 什么是序列(Sequence)
序列是Python中最基本的数据结构类型,有序且可索引。Python内置的序列类型包括:
| 序列类型 | 是否可变 | 特点 | 符号 |
|---|---|---|---|
| 字符串(str) | ❌ 不可变 | 字符序列,Unicode编码 | ' ' 或 " " |
| 列表(list) | ✅ 可变 | 可存储任意类型,动态数组 | [ ] |
| 元组(tuple) | ❌ 不可变 | 不可修改的有序集合 | ( ) |
| 字节串(bytes) | ❌ 不可变 | 字节序列(0-255) | b' ' |
| 字节数组(bytearray) | ✅ 可变 | 可修改的字节序列 | bytearray() |
1.2 序列的通用操作
所有序列都支持以下操作:
python
# 索引访问
s = "Python"
print(s[0]) # 'P'
print(s[-1]) # 'n'(倒数第一个)
# 切片操作 [start:end:step]
print(s[1:4]) # 'yth'
print(s[::-1]) # 'nohtyP'(反转)
# 成员判断
print('y' in s) # True
# 长度与最值
print(len(s)) # 6
print(max(s)) # 'y'
print(min(s)) # 'P'
二、字符串与列表的转化
2.1 字符串 → 列表
方法1:list() 函数 - 拆分为单个字符
python
s = "Hello"
char_list = list(s)
print(char_list) # ['H', 'e', 'l', 'l', 'o']
方法2:split() 方法 - 按分隔符拆分
python
# 按空格拆分(默认)
sentence = "Python is great"
words = sentence.split()
print(words) # ['Python', 'is', 'great']
# 按指定分隔符拆分
csv_line = "apple,banana,orange"
fruits = csv_line.split(",")
print(fruits) # ['apple', 'banana', 'orange']
# 限制拆分次数
text = "a,b,c,d"
result = text.split(",", 2) # 只拆分成3部分
print(result) # ['a', 'b', 'c,d']
方法3:splitlines() - 按行拆分
python
multiline = """第一行
第二行
第三行"""
lines = multiline.splitlines()
print(lines) # ['第一行', '第二行', '第三行']
2.2 列表 → 字符串
方法:join() 方法
python
# 基础用法:用空字符串连接
chars = ['P', 'y', 't', 'h', 'o', 'n']
word = "".join(chars)
print(word) # 'Python'
# 用指定分隔符连接
words = ['Python', 'is', 'fun']
sentence = " ".join(words)
print(sentence) # 'Python is fun'
# 用逗号连接
items = ['apple', 'banana', 'orange']
csv = ",".join(items)
print(csv) # 'apple,banana,orange'
⚠️ 重要 :
join()只能连接字符串类型的元素,其他类型需先转化
python
# ❌ 错误:直接连接数字列表
numbers = [1, 2, 3]
# result = "".join(numbers) # TypeError!
# ✅ 正确:先转化为字符串
result = "".join(str(n) for n in numbers) # '123'
# 或使用 map
result = "".join(map(str, numbers)) # '123'
2.3 综合案例:字符串处理流水线
python
# 案例:清洗并重组字符串
raw = " Python,Java,C++ "
# 步骤1:去除空格 → "Python,Java,C++"
cleaned = raw.strip()
# 步骤2:拆分为列表 → ['Python', 'Java', 'C++']
languages = cleaned.split(",")
# 步骤3:处理每个元素(转大写)
upper_langs = [lang.upper() for lang in languages] # ['PYTHON', 'JAVA', 'C++']
# 步骤4:用 | 连接 → "PYTHON|JAVA|C++"
result = "|".join(upper_langs)
print(result) # PYTHON|JAVA|C++
三、字符串与元组的转化
3.1 字符串 → 元组
python
# 使用 tuple() 函数,与 list() 类似
s = "Python"
char_tuple = tuple(s)
print(char_tuple) # ('P', 'y', 't', 'h', 'o', 'n')
# 结合 split() 后再转化
data = "2024-02-09"
date_tuple = tuple(data.split("-"))
print(date_tuple) # ('2024', '02', '09')
3.2 元组 → 字符串
python
# 同样使用 join(),但需要确保元素是字符串
t = ('P', 'y', 't', 'h', 'o', 'n')
word = "".join(t)
print(word) # 'Python'
# 包含非字符串元素时
info = ('Alice', 25, 'Engineer')
# 先全部转为字符串
result = " | ".join(str(x) for x in info)
print(result) # 'Alice | 25 | Engineer'
3.3 为什么需要元组?
python
# 元组不可变,适合作为字典的键
locations = {
('北京', '朝阳'): '100000',
('上海', '浦东'): '200000'
}
# 元组拆包(Unpacking)
coordinates = "120.5,30.2"
x, y = coordinates.split(",") # x='120.5', y='30.2'
# 函数返回多个值(实际是返回元组)
def get_min_max(numbers):
return min(numbers), max(numbers) # 返回元组
result = get_min_max([3, 1, 4, 1, 5])
print(result) # (1, 5)
min_val, max_val = result # 直接拆包
四、序列间的相互转化
4.1 转化关系图
字符串(str)
↑ ↓
列表(list) ←→ 元组(tuple)
↑ ↓
集合(set) [注意:无序,去重]
↑ ↓
字典(dict) [需要特定格式]
4.2 列表与元组的转化
python
# 列表 → 元组(冻结数据,防止修改)
lst = [1, 2, 3]
t = tuple(lst)
print(t) # (1, 2, 3)
# 元组 → 列表(需要修改时)
t = (1, 2, 3)
lst = list(t)
lst.append(4)
print(lst) # [1, 2, 3, 4]
4.3 序列与集合的转化
python
# 字符串 → 集合(去重,无序)
s = "banana"
char_set = set(s)
print(char_set) # {'b', 'a', 'n'} (顺序不固定)
# 列表 → 集合(去重)
numbers = [1, 2, 2, 3, 3, 3]
unique = set(numbers)
print(unique) # {1, 2, 3}
# 集合 → 列表(恢复有序,需排序)
sorted_list = sorted(set(numbers)) # [1, 2, 3]
4.4 序列与字典的转化
python
# 列表/元组 → 字典(需要成对数据)
pairs = [('a', 1), ('b', 2), ('c', 3)]
d = dict(pairs)
print(d) # {'a': 1, 'b': 2, 'c': 3}
# 两个列表 → 字典(使用 zip)
keys = ['name', 'age', 'city']
values = ['Alice', 25, 'Beijing']
info = dict(zip(keys, values))
print(info) # {'name': 'Alice', 'age': 25, 'city': 'Beijing'}
# 字典 → 列表(获取键、值或键值对)
d = {'a': 1, 'b': 2}
keys = list(d.keys()) # ['a', 'b']
values = list(d.values()) # [1, 2]
items = list(d.items()) # [('a', 1), ('b', 2)]
五、编码与解码转化
5.1 字符串与字节的本质区别
| 特性 | 字符串(str) | 字节(bytes) |
|---|---|---|
| 存储内容 | 字符(Unicode) | 字节(0-255) |
| 适用场景 | 程序内部处理 | 文件/网络传输 |
| 前缀 | 无 | b |
| 编码 | UTF-8/GBK等 | 无 |
5.2 编码:字符串 → 字节
python
text = "你好,Python"
# 使用 encode() 方法
# UTF-8 编码(推荐,国际通用)
utf8_bytes = text.encode('utf-8')
print(utf8_bytes) # b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8cPython'
# GBK 编码(中文Windows常用)
gbk_bytes = text.encode('gbk')
print(gbk_bytes) # b'\xc4\xe3\xba\xc3\xa3\xacPython'
# 处理编码错误
text_with_emoji = "Hello 🌍"
# strict 模式(默认,遇到错误抛异常)
# utf8_bytes = text_with_emoji.encode('ascii') # UnicodeEncodeError
# ignore 模式:忽略无法编码的字符
safe_bytes = text_with_emoji.encode('ascii', errors='ignore')
print(safe_bytes) # b'Hello '
# replace 模式:用 ? 替换
safe_bytes = text_with_emoji.encode('ascii', errors='replace')
print(safe_bytes) # b'Hello ?'
5.3 解码:字节 → 字符串
python
# 使用 decode() 方法
raw_bytes = b'\xe4\xbd\xa0\xe5\xa5\xbd' # UTF-8编码的"你好"
text = raw_bytes.decode('utf-8')
print(text) # '你好'
# 错误处理
unknown_bytes = b'\xff\xfe' # 可能是错误的编码
try:
text = unknown_bytes.decode('utf-8')
except UnicodeDecodeError:
text = unknown_bytes.decode('utf-8', errors='replace')
print(text) # ''
5.4 常见编码错误
python
# ❌ 错误1:混淆编码
# b'hello'.encode() # AttributeError: 'bytes'对象没有encode方法
# ❌ 错误2:编码不匹配
# gbk_bytes = "中文".encode('gbk')
# gbk_bytes.decode('utf-8') # UnicodeDecodeError
# ✅ 正确做法:用什么编码,就用什么解码
gbk_bytes = "中文".encode('gbk')
print(gbk_bytes.decode('gbk')) # '中文'
六、格式化字符串与序列
6.1 序列数据格式化输出
python
data = ['Alice', 25, 95.5]
# 方法1:% 格式化(旧式,不推荐)
info = "Name: %s, Age: %d, Score: %.1f" % (data[0], data[1], data[2])
# 方法2:str.format()(较新)
info = "Name: {}, Age: {}, Score: {:.1f}".format(*data) # 使用 * 解包序列
# 方法3:f-string(推荐,Python 3.6+)
name, age, score = data # 拆包
info = f"Name: {name}, Age: {age}, Score: {score:.1f}"
# 方法4:从字典格式化
person = {'name': 'Bob', 'age': 30}
info = "Name: {name}, Age: {age}".format(**person) # 使用 ** 解包字典
6.2 序列对齐与填充
python
items = ['Apple', 'Banana', 'Cherry']
# 左对齐,宽度10
for item in items:
print(f"{item:<10}|")
# Apple |
# Banana |
# Cherry |
# 右对齐,补零
numbers = [5, 23, 456]
for n in numbers:
print(f"{n:0>5}")
# 00005
# 00023
# 00456
七、常见问题与易错点
7.1 高频错误速查表
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
'str' object does not support item assignment |
字符串不可变 | 先转为列表修改,再转回字符串 |
sequence item 0: expected str instance, int found |
join()遇到非字符串 | 使用 map(str, ...) 或生成式转换 |
UnicodeDecodeError |
编码不匹配 | 确认编码格式,使用 errors='replace' |
TypeError: unhashable type: 'list' |
列表不能作为字典键 | 转为元组 |
| 列表切片后还是原数据 | 浅拷贝问题 | 使用 copy.deepcopy() |
7.2 字符串修改的"曲线救国"
python
# 需求:将 "Hello World" 改为 "Hello Python"
s = "Hello World"
# ❌ 直接修改会报错
# s[6:] = "Python" # TypeError
# ✅ 方法1:切片拼接
new_s = s[:6] + "Python" # 'Hello Python'
# ✅ 方法2:转为列表修改
char_list = list(s)
char_list[6:] = list("Python")
new_s = "".join(char_list)
# ✅ 方法3:使用 replace()
new_s = s.replace("World", "Python")
7.3 性能优化建议
python
# ❌ 低效:循环中反复拼接字符串(产生大量临时对象)
result = ""
for i in range(10000):
result += str(i) # 每次都要创建新字符串
# ✅ 高效:使用列表收集,最后 join
parts = []
for i in range(10000):
parts.append(str(i))
result = "".join(parts)
# ✅ 更高效:使用生成器表达式(节省内存)
result = "".join(str(i) for i in range(10000))
7.4 面试常考代码片段
python
# Q1: 如何快速反转字符串?
s = "Python"
print(s[::-1]) # 'nohtyP'
# Q2: 如何判断字符串是否为回文?
def is_palindrome(s):
return s == s[::-1]
# Q3: 如何去除字符串中的所有空格?
s = " P y t h o n "
no_space = s.replace(" ", "") # 'Python'
# Q4: 如何统计字符出现次数?
from collections import Counter
s = "banana"
count = Counter(s) # Counter({'a': 3, 'n': 2, 'b': 1})
附录:速查表
转化方法总览
| 转化方向 | 方法 | 示例 |
|---|---|---|
| 字符串 → 列表 | list(s) / s.split() |
list("ab") → ['a','b'] |
| 列表 → 字符串 | "".join(lst) |
"".join(['a','b']) → 'ab' |
| 字符串 → 元组 | tuple(s) |
tuple("ab") → ('a','b') |
| 元组 → 字符串 | "".join(t) |
"".join(('a','b')) → 'ab' |
| 列表 ↔ 元组 | tuple(lst) / list(t) |
tuple([1,2]) → (1,2) |
| 字符串 → 字节 | s.encode('utf-8') |
"中".encode() → b'\xe4\xb8\xad' |
| 字节 → 字符串 | b.decode('utf-8') |
b'\xe4\xb8\xad'.decode() → '中' |
这份指南涵盖了Python序列与字符串转化的核心知识点。建议你在学习时配合实际编码练习,特别是多动手写一些数据清洗和格式转换的小程序,这样能更好地掌握这些基础但重要的操作。