一、列表常用方法总结图

二、列表
作为一名测试工程师,我们每天都在和列表打交道。它不仅仅是存储数据的容器,更是我们实现测试逻辑、提升自动化效率的核心工具。
以下是梳理的,在日常工作中关于Python列表的实践总结,以列表形式呈现,方便你快速回顾和应用。
Python列表在测试工作中的高级应用实践总结
1. 🚀 测试数据管理与驱动
-
场景:准备多组测试用例的输入数据,如用户名、搜索关键词、商品ID等。
-
实践 :
- 基础存储:将测试数据直接定义在列表中,方便循环遍历执行。
- 动态生成 :使用列表推导式批量生成规律性数据,极大提升数据准备效率。
- 随机化 :结合
random.choice()或random.sample()从列表中随机选取数据,增加测试的随机性和覆盖面。
-
代码示例 :
python# 基础存储:登录用例数据 login_cases = [ {"user": "valid_user", "pwd": "correct_pwd", "expected": "success"}, {"user": "invalid_user", "pwd": "any_pwd", "expected": "fail"}, ] # 动态生成:100个测试邮箱 test_emails = [f'testuser{i}@example.com' for i in range(100)] # 随机化:从用户列表中随机抽取一个进行测试 users = ['alice', 'bob', 'charlie'] random_user = random.choice(users)
2. 📡 API与数据库响应处理
-
场景:解析API返回的JSON数组,或处理数据库查询结果集。
-
实践 :
- 解析JSON:API返回的JSON数组会直接转换为Python列表,直接操作即可。
- 提取字段:使用列表推导式从复杂对象列表中,快速提取出你关心的单一字段列表。
- 数据验证 :使用
in操作符快速验证某个值(如订单ID)是否存在于返回的列表中。
-
代码示例 :
python# API返回的用户列表 api_response = [ {"id": 101, "name": "Alice"}, {"id": 102, "name": "Bob"}, {"id": 103, "name": "Charlie"} ] # 提取所有用户ID,用于后续断言 user_ids = [user['id'] for user in api_response] # 结果: [101, 102, 103] # 验证ID为102的用户是否在返回列表中 assert 102 in user_ids
3. ⚙️ 参数化与批量执行
-
场景 :使用
pytest等框架,实现一个测试用例对应多组输入和输出的参数化测试。 -
实践 :
pytest.mark.parametrize:其核心参数就是一个列表,列表中的每个元素都是一个元组,代表一组测试数据。
-
代码示例 :
pythonimport pytest # 每个元组是一组 (输入, 预期输出) test_data = [ ("admin", "admin123", True), ("guest", "guest123", False), ("", "any", False) ] @pytest.mark.parametrize("username, password, expected_success", test_data) def test_login(username, password, expected_success): # ... 执行登录逻辑 ... # actual_success = login(username, password) # assert actual_success == expected_success pass
4. 📊 结果聚合与断言
-
场景:在测试执行过程中,收集所有失败的断言信息,或在测试结束后汇总所有测试结果。
-
实践 :
- 收集失败信息 :创建一个空列表,在
try...except AssertionError块中,将失败信息append进去。 - 最终报告:测试结束后,遍历这个失败列表,生成一份清晰的错误报告。
- 收集失败信息 :创建一个空列表,在
-
代码示例 :
pythonfailed_assertions = [] def check_number(n): try: assert n > 10, f"数字 {n} 不大于10" assert n % 2 == 0, f"数字 {n} 不是偶数" except AssertionError as e: failed_assertions.append(str(e)) for num in [5, 12, 9, 20]: check_number(num) # 测试结束后,统一输出所有失败信息 if failed_assertions: print("发现以下断言失败:") for fail_msg in failed_assertions: print(f"- {fail_msg}")
5. 🔧 数据清洗与转换
-
场景:处理从CSV或日志文件中读取的原始数据,去除空格、转换类型等。
-
实践 :
- 批量处理 :使用列表推导式或
map()函数,对列表中的每个元素应用相同的处理函数,代码更简洁、高效。 - 数据过滤 :使用列表推导式或
filter()函数,根据条件过滤掉不需要的数据。
- 批量处理 :使用列表推导式或
-
代码示例 :
python# 原始数据,可能包含空格和字符串格式的数字 raw_data = [" 123 ", " 456", "789 ", "abc", " "] # 数据清洗:去除空格并过滤掉非数字和空字符串 cleaned_numbers = [ int(item.strip()) for item in raw_data if item.strip().isdigit() ] # 结果: [123, 456, 789]
高级技巧与性能考量
-
in操作符的复杂度 :对于列表my_list,x in my_list的时间复杂度是 O(n),即需要遍历整个列表。当列表非常大且需要频繁查找时,应优先考虑使用set(集合) ,其查找复杂度为 O(1)。python# 当数据量大且需要频繁查找时 user_ids_list = [101, 102, ... , 1000000] # 慢 user_ids_set = {101, 102, ... , 1000000} # 快! assert 500123 in user_ids_set -
列表推导式 vs
for循环 :列表推导式不仅代码更紧凑,其底层实现通常也比手动的for循环 +append略快,是更"Pythonic"的选择。
总结:列表是测试工程师的"瑞士军刀"。熟练运用它,能让你的测试数据管理更灵活、测试逻辑更清晰、代码更高效。从简单的数据存储,到驱动复杂的参数化测试和结果分析,列表都是贯穿始终的基石。
三、列表基础使用指南:
数据结构
1、列表作为栈使用
列表方法使得列表作为堆栈非常容易,最后一个插入,最先取出("后进先出")。要添加一个元素到堆栈的顶端,使用 append() 。要从堆栈顶部取出一个元素,使用 pop() ,不用指定索引。
python
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
2、用列表实现队列
列表也可以用作队列,其中先添加的元素被最先取出 ("先进先出");然而列表用作这个目的相当低效。因为在列表的末尾添加和弹出元素非常快,但是在列表的开头插入或弹出元素却很慢 (因为所有的其他元素都必须移动一位)。
若要实现一个队列,可使用 [collections.deque](https://link.zhihu.com/?target=https%3A//docs.python.org/zh-cn/3.7/library/collections.html%23collections.deque),它被设计成可以快速地从两端添加或弹出元素。例如
plain
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry arrives
>>> queue.append("Graham") # Graham arrives
>>> queue.popleft() # The first to arrive now leaves
'Eric'
>>> queue.popleft() # The second to arrive now leaves
'John'
>>> queue # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
3、列表复制
一个列表的数据复制到另一个列表中
**题目:**将一个列表的数据复制到另一个列表中。
**程序分析:**使用列表[:],拿不准可以调用copy模块。
应用场景:
plain
import copy
a = [1,2,3,4,['a','b']]
b = a # 赋值
c = a[:] # 浅拷贝
d = copy.copy(a) # 浅拷贝
e = copy.deepcopy(a) # 深拷贝
a.append(5)
a[4].append('c')
print('a=',a)
print('b=',b)
print('c=',c)
print('d=',d)
print('e=',e)
============ RESTART: F:\PyWorkspace\Python100\100examples\007.py ============
a= [1, 2, 3, 4, ['a', 'b', 'c'], 5]
b= [1, 2, 3, 4, ['a', 'b', 'c'], 5]
c= [1, 2, 3, 4, ['a', 'b', 'c']]
d= [1, 2, 3, 4, ['a', 'b', 'c']]
e= [1, 2, 3, 4, ['a', 'b']]
四、列表基本操作
1、向List中添加元素的方法
1.1 Python append()方法添加元素
python
append() 方法用于在列表的末尾追加元素,该方法的语法格式如下:
listname.append(obj)
其中,listname 表示要添加元素的列表;obj 表示到添加到列表末尾的数据,它可以是单个元素,也可以是列表、元组等。
1.2 Python extend()方法添加元素
python
l = ['Python', 'C++', 'Java'] # 追加元素
l.extend('C')
print(l)
# 追加元组,元祖被拆分成多个元素
t = ('JavaScript', 'C#', 'Go')
l.extend(t)
print(l)
# 追加列表,列表也被拆分成多个元素
l.extend(['Ruby', 'SQL']) print(l)
运行结果:
python
['Python', 'C++', 'Java', 'C']
['Python', 'C++', 'Java', 'C', 'JavaScript', 'C#', 'Go']
['Python', 'C++', 'Java', 'C', 'JavaScript', 'C#', 'Go', 'Ruby', 'SQL']
1.3 Python insert()方法插入元素
python
append() 和 extend() 方法只能在列表末尾插入元素,如果希望在列表中间某个位置插入元素,那么可以使用 insert() 方法。
insert() 的语法格式如下:
listname.insert(index,obj)
其中,index 表示指定位置的索引值。insert() 会将 obj 插入到 listname 列表第 index 个元素的位置。 当插入列表或者元祖时,insert() 也会将它们视为一个整体,作为一个元素插入到列表中,这一点和 append() 是一样的。
2、向List中删除元素的方法
2.1 del:根据索引值删除元素
python
del listname[index]
其中,listname 表示列表名称,index 表示元素的索引值。 del 也可以删除中间一段连续的元素,
格式为:
del listname[start : end]
2.2 pop():根据索引值删除元素
python
Python pop() 方法用来删除列表中指定索引处的元素,
具体格式如下:
listname.pop(index)
其中,listname 表示列表名称,index 表示索引值。如果不写 index 参数,默认会删除列表中的最后一个元素,类似于数据结构中的"出栈"操作。
大部分编程语言都会提供和 pop() 相对应的方法,就是 push() ,该方法用来将元素添加到列表的尾部,类似于数据结构中的"入栈"操作。
2.3 remove():根据元素值进行删除
除了 del 关键字,Python 还提供了 remove() 方法,该方法会根据元素本身的值来进行删除操作。
需要注意的是,remove() 方法只会删除第一个和指定值相同的元素,而且必须保证该元素是存在的,否则会引发 ValueError 错误。
python
nums = [40, 36, 89, 2, 36, 100, 7]
#第一次删除36
nums.remove(36)
print(nums)
#第二次删除36
nums.remove(36)
print(nums)
#删除78
nums.remove(78)
print(nums)
运行结果:
python
[40, 89, 2, 36, 100, 7]
[40, 89, 2, 100, 7]
Traceback (most recent call last):
File "C:\Users\mozhiyan\Desktop\demo.py", line 9, in <module>
nums.remove(78)
ValueError: list.remove(x): x not in list
最后一次删除,因为 78 不存在导致报错,所以我们在使用 remove() 删除元素时最好提前判断一下。
2.4 clear():删除列表所有元素
Python clear() 用来删除列表的所有元素,也即清空列表,
请看下面的代码:
python
url = list("http://c.biancheng.net/python/")
url.clear()
print(url)
运行结果:
3、list列表修改元素
3.1 修改单个元素
python
nums = [40, 36, 89, 2, 36, 100, 7]
nums[2] = -26 #使用正数索引
nums[-3] = -66.2 #使用负数索引
print(nums)
运行结果:
40, 36, -26, 2, -66.2, 100, 7
3.2 修改一组元素
Python 支持通过切片语法给一组元素赋值。在进行这种操作时,如果不指定步长(step 参数),Python 就不要求新赋值的元素个数与原来的元素个数相同;这意味,该操作既可以为列表添加元素,也可以为列表删除元素。
python
nums = [40, 36, 89, 2, 36, 100, 7]
#修改第 1~4 个元素的值(不包括第4个元素)
nums[1: 4] = [45.25, -77, -52.5]
print(nums)
运行结果:
40, 45.25, -77, -52.5, 36, 100, 7
4、list列表查找元素
4.1 index() 方法
python
index() 方法用来查找某个元素在列表中出现的位置(也就是索引),如果该元素不存在,则会导致 ValueError 错误,所以在查找之前最好使用 count() 方法判断一下。
index() 的语法格式为:
listname.index(obj,start,end)
其中,listname 表示列表名称,obj 表示要查找的元素,start 表示起始位置,end 表示结束位置。
4.2 count()方法
5、切片
python
#创建一个数字列表,代表我有100页文章,然后进行分页显示
mage=list(range(1,101))
max_count=len(mage) #使用len()获取列表的长度,上节学的
n=0
while n<max_count: #这里用到了一个while循环,穿越过来的
print(mage[n:n+10]) #这里就用到了切片,这一节的重点
n=n+10
输出
python
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
[21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
[31, 32, 33, 34, 35, 36, 37, 38, 39, 40]
[41, 42, 43, 44, 45, 46, 47, 48, 49, 50]
[51, 52, 53, 54, 55, 56, 57, 58, 59, 60]
[61, 62, 63, 64, 65, 66, 67, 68, 69, 70]
[71, 72, 73, 74, 75, 76, 77, 78, 79, 80]
[81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
[91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
6. 序列通用操作
(1)# + 和 *
python
# + 和 *
# +可以将两个列表拼接为一个列表
my_list = [1,2,3] + [4,5,6]
# * 可以将列表重复指定的次数
my_list = [1,2,3] * 5
# print(my_list)
(2)创建一个列表
python
# 创建一个列表
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精','沙和尚','沙和尚']
(3)in 和 not in
python
# in 和 not in
# in用来检查指定元素是否存在于列表中
# 如果存在,返回True,否则返回False
# not in用来检查指定元素是否不在列表中
# 如果不在,返回True,否则返回False
# print('牛魔王' not in stus)
# print('牛魔王' in stus)
(4)len()获取列表中的元素的个数
python
arr = [10,1,2,5,100,77]
# print(len(arr) )
(5)min() 获取列表中的最小值
python
arr = [10,1,2,5,100,77]
# print(min(arr))
(6)max() 获取列表中的最大值
python
arr = [10,1,2,5,100,77]
# print(max(arr))
(7)s.index() 获取指定元素在列表中的第一次出现时索引
python
# 两个方法(method),方法和函数基本上是一样,只不过方法必须通过 对象.方法() 的形式调用
# xxx.print() 方法实际上就是和对象关系紧密的函数
# s.index() 获取指定元素在列表中的第一次出现时索引
# print(stus.index('沙和尚'))
# index()的第二个参数,表示查找的起始位置 , 第三个参数,表示查找的结束位置
# print(stus.index('沙和尚',3,7))
# 如果要获取列表中没有的元素,会抛出异常
# print(stus.index('牛魔王')) ValueError: '牛魔王' is not in list
(8)s.count() 统计指定元素在列表中出现的次数
python
# s.count() 统计指定元素在列表中出现的次数
print(stus.count('牛魔王'))
(9) 修改列表元素
创建一个列表
python
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']
修改列表中的元素:直接通过索引来修改元素
python
stus[0] = 'sunwukong'
stus[2] = '哈哈'
通过del来删除元素
python
del stus[2] # 删除索引为2的元素
# print('修改后:',stus)
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']
通过切片来修改列表:在给切片进行赋值时,只能使用序列
python
# stus[0:2] = ['牛魔王','红孩儿'] 使用新的元素替换旧元素
# stus[0:2] = ['牛魔王','红孩儿','二郎神']
# stus[0:0] = ['牛魔王'] # 向索引为0的位置插入元素
# 当设置了步长时,序列中元素的个数必须和切片中元素的个数一致
# stus[::2] = ['牛魔王','红孩儿','二郎神']
(10)切片
切片语法
python
切片
# 切片指从现有列表中,获取一个子列表
# 创建一个列表,一般创建列表时,变量的名字会使用复数
stus = ['孙悟空','猪八戒','沙和尚','唐僧','蜘蛛精','白骨精']
# 列表的索引可以是负数
# 如果索引是负数,则从后向前获取元素,-1表示倒数第一个,-2表示倒数第二个 以此类推
# print(stus[-2])
# 通过切片来获取指定的元素
# 语法:列表[起始:结束]
# 通过切片获取元素时,会包括起始位置的元素,不会包括结束位置的元素
# 做切片操作时,总会返回一个新的列表,不会影响原来的列表
# 起始和结束位置的索引都可以省略不写
# 如果省略结束位置,则会一直截取到最后
# 如果省略起始位置,则会从第一个元素开始截取
# 如果起始位置和结束位置全部省略,则相当于创建了一个列表的副本
# print(stus[1:])
# print(stus[:3])
# print(stus[:])
# print(stus)
# 语法:列表[起始:结束:步长]
# 步长表示,每次获取元素的间隔,默认值是1
# print(stus[0:5:3])
# 步长不能是0,但是可以是负数
# print(stus[::0]) ValueError: slice step cannot be zero
# 如果是负数,则会从列表的后部向前边取元素
print(stus[::-1])
通过切片来删除元素
python
# del stus[0:2]
# del stus[::2]
# stus[1:3] = []
# print('修改后:',stus)
# 以上操作,只适用于可变序列
s = 'hello'
# s[1] = 'a' 不可变序列,无法通过索引来修改
# 可以通过 list() 函数将其他的序列转换为list
s = list(s)
print(s)
(11)遍历列表
for循环遍历:
python
lists = ["m1", 1900, "m2", 2000]
for item in lists:
print(item)
lists = ["m1", 1900, "m2", 2000]
for item in lists:
item = 0;
print(lists)
##运行结果
['m1', 1900, 'm2', 2000]
while循环遍历:
python
lists = ["m1", 1900, "m2", 2000]
count = 0
while count < len(lists):
print(lists[count])
count = count + 1
索引遍历:
python
for index in range(len(lists)):
print(lists[index])
使用iter():
python
for val in iter(lists):
print(val)
enumerate遍历方法:
python
for i, val in enumerate(lists):
print(i, val)
运行结果:
python
0 m1
1 1900
2 m2
3 2000
当从非0下标开始遍历元素的时候可以用如下
python
for i, el in enumerate(lists, 1):
print(i, el)
运行结果:
python
1 m1
2 1900
3 m2
4 2000
逆序遍历
python
a = [1,3,6,8,9]
print("通过下标逆序遍历1:")
for i in a[::-1]:
print(i, end=" ")
print("\n通过下标逆序遍历2:")
for i in range(len(a)-1,-1,-1):
print(a[i], end=" ")
print("\n通过reversed逆序遍历:")
for i in reversed(a):
print(i, end=" ")
输出
python
通过下标逆序遍历1:
9 8 6 3 1
通过下标逆序遍历2:
9 8 6 3 1
通过reversed逆序遍历:
9 8 6 3 1
往前遍历列表
python
ists = [0, 1, 2, 3, 4, 5]
# 输出 5, 4, 3, 2, 1, 0
for i in range(5, -1, -1):
print(lists[i])
# 输出5, 4, 3
for i in range(5, 2, -1):
print(lists[i])