Python 数据序列(字符串、列表、元组、字典、集合)通关指南:从基础语法到面试实战
Python 数据序列是编程入门的核心基石,也是求职 IT 岗位时面试官高频追问的考点。本文结合 Python 基础教学讲义内容,从字符串、列表、元组、字典、集合的核心语法出发,搭配实战代码与通俗解释,同时补充高频扩展知识点和带关键代码的面试真题,帮你吃透数据序列,实现学以致用。
目录
一、字符串:Python 最常用的基础序列
字符串是 Python 中处理文本数据的核心类型,掌握其操作是文本处理的第一步。
1. 字符串的定义与输入输出
- 定义:支持单引号、双引号、三引号,注意嵌套引号的转义问题。
- 输入:
input()方法接收的所有数据默认是字符串类型。 - 输出:支持普通输出、% 格式化、
format()、f-string(推荐)。
# 1. 字符串定义的多种方式
str1 = 'hello' # 单引号
str2 = "I'm Tom" # 双引号解决单引号嵌套
str3 = '''Hello
World''' # 三引号支持换行
# 2. 输入与输出
name = input("请输入姓名:")
age = input("请输入年龄:")
# f-string格式化(推荐,支持表达式和格式控制)
print(f"姓名:{name},年龄:{age},明年年龄:{int(age)+1}")
# 保留两位小数的格式控制
price = 18.5
print(f"购买商品名称:{name},商品价格:{price:.2f}")
代码解释:
- 三引号可直接写多行文本,无需手动加换行符
\n; - f-string 是 Python3.6 + 的特性,既简洁又支持变量和表达式,是实际开发中最常用的格式化方式;
:.2f用于控制浮点数保留两位小数,适配价格、金额等场景。
2. 字符串切片:“顾头不顾尾” 的截取技巧
切片是字符串(及列表、元组)的核心操作,语法为序列[起始下标:结束下标:步长],口诀是 “只顾头来尾不管,步长为正正向移,步长为负则逆向移”,更多知识点见:https://blog.csdn.net/2301_80137277/article/details/145556916?spm=1001.2014.3001.5501
s = "0123456789"
# 基础切片:截取索引2-4(不包含4)
print(s[2:5]) # 输出"234"
# 省略起始:从开头截取到索引5(不包含5)
print(s[:5]) # 输出"01234"
# 省略结束:从索引1截取到末尾
print(s[1:]) # 输出"123456789"
# 步长为2:隔一个取一个
print(s[::2]) # 输出"02468"
# 步长为负:字符串反转
print(s[::-1]) # 输出"9876543210"
代码解释:
- 切片的 “顾头不顾尾” 是指包含起始下标对应的字符,不包含结束下标对应的字符;
- 步长为负数时会从右往左截取,是实现字符串反转的极简方案。
3. 字符串内置方法:查找、修改与判断
| 方法分类 | 核心方法 | 功能说明 |
|---|---|---|
| 查找 | find() |
找子串,存在返回起始下标,不存在返回 - 1 |
index() |
与 find 功能一致,不存在则报异常 | |
| 修改 | replace() |
替换子串,可指定替换次数 |
split() |
按分隔符切割字符串为列表 | |
join() |
用字符串拼接序列为新字符串 | |
| 判断 | isalpha() |
判断是否全为字母 |
isdigit() |
判断是否全为数字 |
s = "hello python hello linux"
# 1. 查找方法
print(s.find("hello")) # 0(返回第一个匹配的下标)
print(s.find("java")) # -1(不存在返回-1)
# print(s.index("java")) # 报错(index不存在会抛ValueError)
# 2. 修改方法
print(s.replace("linux", "python", 1)) # 替换第一个linux为python
print(s.split(" ")) # 按空格切割:['hello', 'python', 'hello', 'linux']
print("-".join(["apple", "banana"])) # 拼接为apple-banana
# 3. 判断方法
print("abc123".isalpha()) # False(含数字)
print("123456".isdigit()) # True(全为数字)
扩展知识点:实际开发中常用strip()去除字符串首尾空格 / 换行符,upper()/lower()实现大小写转换:
s = " hello world \n"
print(s.strip()) # 输出"hello world"(去除首尾空白)
print(s.upper()) # 输出" HELLO WORLD \n"
面试高频题(附关键代码)
-
题目:请实现一个函数,统计字符串中每个字符的出现次数(要求区分大小写,忽略空格)
def count_char(s): char_dict = {} for c in s: if c == " ": continue char_dict[c] = char_dict.get(c, 0) + 1 return char_dict test_str = "Hello World" print(count_char(test_str)) # {'H':1, 'e':1, 'l':3, 'o':2, 'W':1, 'r':1, 'd':1}代码解释:用字典存储字符计数,
get()方法避免键不存在报错,通过循环遍历字符串实现统计。 -
题目:
find()和index()的核心区别是什么?答:子串不存在时,find()返回 - 1,index()抛出ValueError,前者更安全。关键验证代码:s = "abc" print(s.find("d")) # -1 # print(s.index("d")) # 抛出ValueError: substring not found
二、列表:可变有序的 “数据容器”
列表是 Python 中最灵活的序列类型,可存储不同类型数据,支持增删改查,是批量数据处理的核心工具。
1. 列表的定义与基础操作
列表用[]定义,支持append()(尾部追加)、extend()(追加序列)、insert()(指定位置插入)等增操作,以及del、pop()、remove()等删操作。
# 定义列表(支持不同数据类型)
fruit_list = ["apple", "banana", 100]
# 1. 增操作
fruit_list.append("orange") # 尾部追加单个元素:["apple", "banana", 100, "orange"]
fruit_list.extend(["grape", "pear"]) # 追加序列:["apple", "banana", 100, "orange", "grape", "pear"]
fruit_list.insert(1, "mango") # 索引1处插入:["apple", "mango", "banana", 100, "orange", "grape", "pear"]
# 2. 删操作
del fruit_list[3] # 删除索引3的元素(100)
fruit_list.pop() # 删除最后一个元素(pear)
fruit_list.remove("banana") # 删除第一个匹配的banana
print(fruit_list) # 最终结果:["apple", "mango", "orange", "grape"]
代码解释:
append()和extend()的区别:前者加单个元素,后者加序列(如列表、字符串),若用append()加列表会导致嵌套;pop()可指定索引,且会返回删除的元素,remove()只能按元素值删除第一个匹配项。
2. 列表嵌套与遍历
列表可嵌套形成 “二维列表”(类似二维数组),常用于存储结构化数据。
# 嵌套列表:存储3个班级的学生
classes = [["张三", "李四"], ["王五", "赵六"], ["田七", "钱八"]]
# 访问二班的赵六
print(classes[1][1]) # 赵六
# 遍历嵌套列表
for cls in classes:
for student in cls:
print(student, end=" ")
print()
扩展知识点:sort()与sorted()的区别
list.sort():原地排序,修改原列表,无返回值;sorted(list):返回新的排序后的列表,原列表不变,支持reverse=True指定降序。
nums = [3, 1, 4, 2]
nums.sort() # 原列表变为[1,2,3,4]
new_nums = sorted(nums, reverse=True) # 新列表[4,3,2,1],原列表不变
面试高频题(附关键代码)
-
题目:给定一个嵌套列表
[[1,2],[3,4],[5,6]],请将其展平为一维列表matrix = [[1,2],[3,4],[5,6]] # 方法1:列表推导式 flat_list = [num for sublist in matrix for num in sublist] print(flat_list) # [1,2,3,4,5,6] # 方法2:循环拼接 flat_list2 = [] for sublist in matrix: flat_list2.extend(sublist) print(flat_list2) # [1,2,3,4,5,6]代码解释:列表推导式通过嵌套循环实现展平,是最简洁的方式;循环拼接则通过
extend()逐个子列表合并。 -
题目:如何实现列表去重?
nums = [1,2,2,3,3,3] # 方法1:转集合(打乱顺序) unique1 = list(set(nums)) print(unique1) # [1,2,3](顺序不固定) # 方法2:列表推导式(保留原顺序) unique2 = [x for i, x in enumerate(nums) if x not in nums[:i]] print(unique2) # [1,2,3]代码解释:集合自动去重但无序;列表推导式通过判断元素是否首次出现,保留原顺序。
三、元组:不可变的 “安全容器”
元组用()定义,特性是不可变性(元素不可修改),适合存储固定数据(如配置参数),性能优于列表。
1. 元组的定义与注意事项
定义单元素元组时必须加逗号,否则会被识别为普通数据类型。
# 正确定义元组
t1 = (10, 20, 30) # 多元素元组
t2 = (50,) # 单元素元组(必须加逗号)
t3 = tuple([1,2,3]) # 从列表转元组
# 错误定义:t4会被识别为int类型,而非元组
t4 = (50)
print(type(t4)) # <class 'int'>
# 元组的查询操作(无增删改)
print(t1[1]) # 20(按索引访问)
print(t1.count(20)) # 1(统计元素出现次数)
print(t1.index(30)) # 2(查找元素下标)
扩展知识点:元组的性能优势元组因不可变,Python 会对其进行内存优化,访问速度比列表快;且元组可作为字典的键、集合的元素,列表则不行(因列表可变,不可哈希)。
面试高频题(附关键代码)
-
题目:元组中包含可变元素(如列表),能否修改可变元素内部?
t = (1, [2,3], 4) t[1][0] = 20 # 修改元组内列表的元素 print(t) # (1, [20, 3], 4) # t[0] = 10 # 报错,元组本身的元素引用不可变代码解释:元组的不可变指元素的内存地址不可变,若元素是可变类型(如列表),其内部数据可修改。
-
题目:列表和元组的核心区别?答:① 可变性:列表可变,元组不可变;② 性能:元组更快;③ 用途:列表用于动态数据,元组用于固定数据 / 哈希场景。验证性能的关键代码(需导入 time 模块):
import time lst = list(range(1000000)) tpl = tuple(range(1000000)) start1 = time.time() for i in lst: pass print(f"列表遍历耗时:{time.time()-start1:.6f}s") start2 = time.time() for i in tpl: pass print(f"元组遍历耗时:{time.time()-start2:.6f}s") # 耗时更短
四、字典:键值对的 “映射神器”
字典用{key:value}定义,是键值对结构,可快速通过键查找值,是存储结构化信息(如用户信息)的核心工具。
1. 字典的增删改查
字典支持keys()(取所有键)、values()(取所有值)、items()(取键值对),且推荐用get()方法避免键不存在报错。
# 定义用户信息字典
user = {"name": "Tom", "age": 20, "address": "长沙"}
# 1. 增/改操作(key存在则改,不存在则增)
user["gender"] = "男" # 新增gender键
user["age"] = 21 # 修改age的值
# 2. 查操作(推荐get方法,避免KeyError)
print(user.get("name")) # Tom
print(user.get("phone", "123456")) # 键不存在返回默认值123456
# 遍历键值对
for k, v in user.items():
print(f"{k}: {v}")
# 3. 删操作
del user["address"] # 删除指定键
user.clear() # 清空字典
扩展知识点:collections.defaultdict处理默认值当需要为不存在的键设置默认类型(如列表)时,defaultdict比get()更高效:
from collections import defaultdict
# 统计字符出现次数
char_count = defaultdict(int)
s = "hello"
for c in s:
char_count[c] += 1
print(char_count) # defaultdict(<class 'int'>, {'h':1, 'e':1, 'l':2, 'o':1})
面试高频题(附关键代码)
-
题目:如何高效合并两个字典?
dict1 = {"a":1, "b":2} dict2 = {"b":3, "c":4} # Python3.9+ 方法 merged1 = dict1 | dict2 print(merged1) # {'a':1, 'b':3, 'c':4} # 低版本方法 merged2 = {**dict1, **dict2} print(merged2) # {'a':1, 'b':3, 'c':4}代码解释:
|运算符是 Python3.9 新增的字典合并语法;{**dict1,**dict2}通过解包实现合并,后者兼容性更强。 -
题目:字典的键可以是哪些数据类型?答:必须是可哈希类型(不可变类型),如 int、str、tuple;列表、字典等可变类型不能作为键。验证代码:
# 合法键 d1 = {(1,2): "tuple_key", "str": 123, 10: "int_key"} print(d1) # 非法键(报错) # d2 = {[1,2]: "list_key"} # TypeError: unhashable type: 'list'
五、集合:无序去重的 “数据工具”
集合用{}或set()定义,特性是无序、不重复,常用于去重、交并补差等集合运算。
1. 集合的基础操作
集合支持add()(加单个元素)、remove()(删元素,不存在报错)、discard()(删元素,不存在不报错),以及&(交集)、|(并集)、-(差集)等运算。
# 定义集合(自动去重)
s1 = {1, 2, 2, 3}
print(s1) # {1,2,3}
# 增删操作
s1.add(4) # {1,2,3,4}
s1.discard(5) # 删不存在的元素不报错
s1.remove(3) # 删存在的元素:{1,2,4}
# 集合运算
s2 = {2, 4, 5, 6}
print(s1 & s2) # 交集{2,4}
print(s1 | s2) # 并集{1,2,4,5,6}
print(s1 - s2) # 差集{1}
扩展知识点:frozenset不可变集合普通集合可变,不能作为字典的键;frozenset是不可变集合,可用于哈希场景:
fs = frozenset([1,2,3])
d = {fs: "不可变集合"}
print(d) # {frozenset({1,2,3}): '不可变集合'}
面试高频题(附关键代码)
-
题目:给定两个大列表,如何快速找出它们的共同元素?
list1 = [1,2,3,4,5] list2 = [4,5,6,7,8] # 转集合求交集,效率远高于双重循环 common = list(set(list1) & set(list2)) print(common) # [4,5]代码解释:集合的交集运算时间复杂度为 O (min (len (list1),len (list2))),远优于双重循环的 O (n²)。
-
题目:集合去重的原理是什么?
答:基于哈希表实现,重复元素的哈希值相同,会被自动合并,因此集合元素必须是可哈希类型
lst = ["a", "b", "a", "c"]
s = set(lst)
print(s) # {'a','b','c'}
print(list(s)) # 转回列表实现去重
六、公共方法与列表推导式:效率提升利器
1. 数据序列公共方法
所有序列支持+(合并)、*(复制)、in/not in(判断存在)、max/min(最值),以及list()/tuple()/set()的容器转换。
# 1. 合并与复制
list1 = [1,2]
list2 = [3,4]
print(list1 + list2) # 合并[1,2,3,4]
print(list1 * 3) # 复制[1,2,1,2,1,2]
# 2. 容器转换
t = (1,2,3)
print(list(t)) # 元组转列表[1,2,3]
print(set(t)) # 元组转集合{1,2,3}
2. 列表推导式:一行代码生成列表
列表推导式是 Python 的 “语法糖”,可快速生成有规律的列表,支持if条件和嵌套循环,比普通 for 循环更简洁高效。
# 基础推导式:生成0-9的列表
nums = [i for i in range(10)]
print(nums) # [0,1,2,3,4,5,6,7,8,9]
# 带if条件:生成0-20的偶数
evens = [i for i in range(21) if i % 2 == 0]
print(evens) # [0,2,4,...,20]
# 嵌套循环:生成(1,0),(1,1),(2,0),(2,1)
pairs = [(i,j) for i in range(1,3) for j in range(2)]
print(pairs) # [(1,0), (1,1), (2,0), (2,1)]
扩展知识点:字典 / 集合推导式
推导式可扩展到字典和集合,进一步提升代码效率:
# 字典推导式:生成数字-平方的映射
square_dict = {i: i**2 for i in range(5)}
print(square_dict) # {0:0, 1:1, 2:4, 3:9, 4:16}
# 集合推导式:生成1-10的平方去重(示例无重复)
square_set = {i**2 for i in range(10)}
print(square_set) # {0,1,4,9,16,25,36,49,64,81}
面试高频题(附关键代码)
-
题目:用列表推导式实现矩阵转置(
matrix = [[1,2],[3,4],[5,6]]转置为[[1,3,5],[2,4,6]])matrix = [[1,2],[3,4],[5,6]] transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))] print(transposed) # [[1,3,5], [2,4,6]]代码解释:外层推导式遍历列索引,内层推导式遍历每行的对应列元素,实现行列互换。
-
题目:列表推导式和普通 for 循环的效率差异? 验证代码(需导入 time 模块):
import time
# 普通for循环
start1 = time.time()
lst1 = []
for i in range(1000000):
lst1.append(i)
print(f"for循环耗时:{time.time()-start1:.6f}s")
# 列表推导式
start2 = time.time()
lst2 = [i for i in range(1000000)]
print(f"列表推导式耗时:{time.time()-start2:.6f}s") # 耗时更短
代码解释:列表推导式基于 C 语言底层实现,比 Python 层面的 for 循环更快,尤其是数据量大时。
七、总结
Python 数据序列是编程的 “地基”,从字符串的文本处理到字典的映射存储,从列表的动态操作到集合的去重运算,每个类型都有其专属场景。掌握基础语法的同时,理解底层原理和扩展用法,再结合面试真题的代码实战,就能轻松应对课程学习和求职面试的双重考验。
更多推荐

所有评论(0)