Python列表List基础教程:定义、操作、切片与深拷贝详解
本文系统讲解Python中列表List的核心用法,涵盖定义、索引访问、增删改操作及拼接。重点解析切片语法[start:end:step]、列表推导式的高效构建,以及浅拷贝与深拷贝的区别,通过代码实例演示如何避免引用陷阱并正确复制列表。
Python列表基础概念
序列是Python中最基础的数据结构类型。在序列中,每个元素都被分配一个数字索引,即位置编号,其中首个元素的索引为0,后续元素依次递增。
Python内置了6种序列类型,其中最常用的是列表(List)和元组(Tuple)。
所有序列类型均支持索引、切片、拼接(加)、重复(乘)以及成员资格检查等操作。
此外,Python提供了内置函数来确定序列的长度,以及查找序列中最大和最小元素的方法。
列表是Python中使用频率最高的数据类型,其表现形式为方括号内包含由逗号分隔的值。
列表中的各个数据项无需具备相同的数据类型,可以混合存储。
列表的定义与访问
定义列表
创建列表时,只需将不同的数据项用逗号分隔,并包裹在方括号内即可。具体示例如下:
list1 = ['Google', 'jb51', 2006, 2020];
list2 = [1, 2, 3, 4, 5 ];
list3 = ["a", "b", "c", "d"];
与字符串索引机制类似,列表索引同样从0开始计数。列表支持截取子集和组合拼接等操作。
访问列表中的值
通过下标索引可以访问列表中的特定值,同时也可利用方括号语法进行字符截取,示例如下:
实例(Python 3.0+)
#!/usr/bin/python3
list1 = ['Google', 'jb51', 2006, 2020];
list2 = [1, 2, 3, 4, 5, 6, 7 ];
print ("list1[0]: ", list1[0])
print ("list1[1]: ", list1[1])
print ("list2[1:5]: ", list2[1:5])
上述代码的输出结果如下:
list1[0]: Google list1[1]: jb51 list2[1:5]: [2, 3, 4, 5]
列表的更新与删除
更新列表
你可以直接修改列表中的数据项,或者使用append()方法向列表末尾添加新元素,具体操作如下:
实例(Python 3.0+)
#!/usr/bin/python3
list = ['Baidu', 'jb51', 2006, 2020];
print ("第三个元素为 : ", list[2])
list[2] = 2019
print ("更新后的第三个元素为 : ", list[2])
注意:append()方法的详细用法将在后续章节中深入讨论。
上述代码的输出结果如下:
第三个元素为 : 2006 更新后的第三个元素为 : 2019
删除列表元素
可以使用del语句来删除列表中的指定元素,具体实例如下:
实例(Python 3.0+)
#!/usr/bin/python3
list = ['Baidu', 'jb51', 2006, 2020];
print ("原始列表 : ", list)
del list[2]
print ("删除第三个元素 : ", list)
上述代码的输出结果如下:
原始列表 : ['Baidu', 'jb51', 2006, 2020] 删除第三个元素 : ['Baidu', 'jb51', 2020]
注意:remove()方法的详细用法将在后续章节中深入讨论。
列表操作符与切片拼接
Python列表脚本操作符
列表对+和*运算符的处理方式与字符串相似。+号用于合并两个列表,*号用于重复生成列表。
具体操作示例如下:
| Python 表达式 | 结果 | 描述 |
|---|---|---|
| len([1, 2, 3]) | 3 | 长度 |
| [1, 2, 3] + [4, 5, 6] | [1, 2, 3, 4, 5, 6] | 组合 |
| ['Hi!'] * 4 | ['Hi!', 'Hi!', 'Hi!', 'Hi!'] | 重复 |
| 3 in [1, 2, 3] | True | 元素是否存在于列表中 |
| for x in [1, 2, 3]: print(x, end=" ") | 1 2 3 | 迭代 |
Python列表截取与拼接
Python列表的截取与拼接操作与字符串类似,具体示例如下:
L=['Baidu', 'Jb51', 'Taobao']
具体操作:
| Python 表达式 | 结果 | 描述 |
|---|---|---|
| L[2] | 'Taobao' | 读取第三个元素 |
| L[-2] | 'Jb51' | 从右侧开始读取倒数第二个元素: count from the right |
| L[1:] | ['Jb51', 'Taobao'] | 输出从第二个元素开始后的所有元素 |
>>>L=['Baidu', 'Jb51', 'Taobao']
>>> L[2]
'Taobao'
>>> L[-2]
'Jb51'
>>> L[1:]
['Jb51', 'Taobao']
>>>
列表还额外支持拼接操作:
>>>squares = [1, 4, 9, 16, 25]
>>> squares += [36, 49, 64, 81, 100]
>>> squares
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>>
嵌套列表与函数方法
嵌套列表
嵌套列表是指在列表内部创建其他列表,例如:
>>>a = ['a', 'b', 'c']
>>> n = [1, 2, 3]
>>> x = [a, n]
>>> x
[['a', 'b', 'c'], [1, 2, 3]]
>>> x[0]
['a', 'b', 'c']
>>> x[0][1]
'b'
Python列表函数与方法
Python内置了以下列表相关函数:
| 序号 | 函数 |
|---|---|
| 1 | len(list) 列表元素个数 |
| 2 | max(list) 返回列表元素最大值 |
| 3 | min(list) 返回列表元素最小值 |
| 4 | list(seq) 将元组转换为列表 |
Python内置了以下列表相关方法:
| 序号 | 方法 |
|---|---|
| 1 | list.append(obj) 在列表末尾添加新的对象 |
| 2 | list.count(obj) 统计某个元素在列表中出现的次数 |
| 3 | list.extend(seq) 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
| 4 | list.index(obj) 从列表中找出某个值第一个匹配项的索引位置 |
| 5 | list.insert(index, obj) 将对象插入列表 |
| 6 | list.pop([index=-1]) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
| 7 | list.remove(obj) 移除列表中某个值的第一个匹配项 |
| 8 | list.reverse() 反向列表中元素 |
| 9 | list.sort( key=None, reverse=False) 对原列表进行排序 |
| 10 | list.clear() 清空列表 |
| 11 | list.copy() 复制列表 |
二维列表创建与切片语法
下面分享一些具体的应用实例。
在Python中创建二维列表,只需将所需的参数分别写入cols(列)和rows(行)变量中即可。
list_2d = [[0 for col in range(cols)] for row in range(rows)]
具体实例:
>>> list_2d = [ [0 for i in range(5)] for i in range(5)] >>> list_2d[0].append(3) >>> list_2d[0].append(5) >>> list_2d[2].append(7) >>> list_2d [[0, 0, 0, 0, 0, 3, 5], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 7], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
命名方式与输出内容均清晰展示了列表的结构。
l = [i for i in range(0,15)]
print(l)
print(l[::2])
我们可以观察到l后面跟随了两个冒号以及数字2,其具体效果如下:
l = [i for i in range(0,15)]
print(l)
print(l[::2])
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[0, 2, 4, 6, 8, 10, 12, 14]
我的理解是:
l[start:end:span]
这表示遍历区间[start, end),步长为span。当span大于0时,按顺序遍历;当span小于0时,逆序遍历。
若未指定start,默认值为0;若未指定end,默认值为列表长度。
列表复制与内存机制
列表的复制
>>> a = [1, 2, 3]
>>> b = a
>>> c = []
>>> c = a
>>> d = a[:]
>>> a, b, c, d
([1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3])
>>> b[0] = 'b'
>>> a, b, c, d
(['b', 2, 3], ['b', 2, 3], ['b', 2, 3], [1, 2, 3])
>>> id(a), id(b), id(c), id(d)
(140180778120200, 140180778120200, 140180778120200, 140180778122696)
>>> c[0] = 'c'
>>> a, b, c, d
(['c', 2, 3], ['c', 2, 3], ['c', 2, 3], [1, 2, 3])
>>> id(a), id(b), id(c), id(d)
(140180778120200, 140180778120200, 140180778120200, 140180778122696)
>>> d[0] = 'd'
>>> a, b, c, d
(['c', 2, 3], ['c', 2, 3], ['c', 2, 3], ['d', 2, 3])
>>> id(a), id(b), id(c), id(d)
(140180778120200, 140180778120200, 140180778120200, 140180778122696)
可以看到变量a、b、c具有相同的ID值,这意味着它们指向同一内存地址。当修改其中任一列表元素的值时,这三个变量所引用的列表内容会同步改变。
然而,变量d的元素值保持不变,即使修改d的元素值,其他三个变量内的元素值也不会受到影响。
从a、b、c、d的ID值来看,a、b、c共享完全相同的内存地址,而d被分配了新的内存地址。
因此,在一般情况下,若想复制得到一个独立的新列表,且修改新列表元素时不影响原列表,应采用d的赋值方式。
这种方法仅适用于结构较为单一的普通列表。
关于列表复制的问题,可以使用copy模块中的copy()函数来解决,具体实例如下:
import copy
a = [1,2,3,4]
b = a
d = copy.copy(a)
b[0] = 'b'
print(a,b,d)
print(id(a),id(b),id(d))
前两位同学的回答均正确,此外还可以使用list自带的copy()方法,该方法会重新开辟内存空间来存储新列表。
original_list=[0,1,2,3,4,5,6,7,8] copy_list=original_list.copy() copy_list=copy_list+['a','b','c'] print("original_list:",original_list) print("copy_list modify:",copy_list)
运行结果
original_list: [0, 1, 2, 3, 4, 5, 6, 7, 8] copy_list modify: [0, 1, 2, 3, 4, 5, 6, 7, 8, 'a', 'b', 'c']
空列表可以通过两个中括号[]直接表示,即内部没有任何内容。但如果想创建一个占用十个元素空间、却暂不包含任何有效数据的列表,该如何操作?首先可以采用如下方法,用具体值占位。
>>> list_empty = [0]*10 >>> list_empty [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
这样便生成了一个包含10个0的列表。然而,有时可能需要一个值来代表“空”,即未在列表中放置任何元素。此时应使用None。None是Python的内建值,确切含义为“这里什么也没有”。因此,若需初始化一个长度为10的列表,可按以下示例实现:
>>> list_empty = [None]*10 >>> list_empty [None, None, None, None, None, None, None, None, None, None]
这样即可对列表的各个元素进行后续初始化。
有时在尝试获取list中的元素时,可能会遇到以下情形:
>>> a=[] >>> a[0] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
发生这种情况是因为仅定义了一个空列表,未进行任何赋值操作,导致列表内部为空。报错信息明确指出索引超出范围,即尝试访问的0实际上是第一个值的位置,而由于列表为空且未赋值,故引发错误。
若使用以下语句,则不会报错:
>>> a[0:] []
这并非什么技巧,而是语句意义的不同。该语句实际上输出了列表a中的所有值,其最终结果与以下表达一致。
>>> a[:] []
该语句并不能避免上述索引超出范围的错误,因为这是两种不同意义的语句。a[0:]和a[:]在脚本输出时相当于print(a)的效果。这并非解决错误的方案,不应将其视为技巧使用。
列表推导式与高级应用
感觉缺少了对列表推导式的讲解(该功能非常便捷)。
1、列表推导式的书写形式:
[表达式 for 变量 in 列表] 或者 [表达式 for 变量 in 列表 if 条件]
#!/usr/bin/python
# -*- coding: utf-8 -*-
li = [1,2,3,4,5,6,7,8,9]
print ([x**2 for x in li])
print ([x**2 for x in li if x>5])
print (dict([(x,x*10) for x in li]))
print ([ (x, y) for x in range(10) if x % 2 if x > 3 for y in range(10) if y > 7 if y != 8 ])
vec=[2,4,6]
vec2=[4,3,-9]
sq = [vec[i]+vec2[i] for i in range(len(vec))]
print (sq)
print ([x*y for x in [1,2,3] for y in [1,2,3]])
testList = [1,2,3,4]
def mul2(x):
return x*2
print ([mul2(i) for i in testList])
结果:
[1, 4, 9, 16, 25, 36, 49, 64, 81] [36, 49, 64, 81] {1: 10, 2: 20, 3: 30, 4: 40, 5: 50, 6: 60, 7: 70, 8: 80, 9: 90} [(5, 9), (7, 9), (9, 9)] [6, 7, -3] [1, 2, 3, 2, 4, 6, 3, 6, 9] [2, 4, 6, 8]
3、总结:
我认为核心是通过for语句处理表达式中的变量,若需增加条件判断,只需添加if条件即可。
在此教程中未提及列表的切片操作,在此简要说明。
格式:【start:end:step】
start:起始索引,从0开始,-1表示结束 end:结束索引 step:步长,end-start,步长为正时,从左向右取值;步长为负时,反向取值。
举例说明:
>>> a=[1,2,3,4]
>>> b='abcdef'
>>> print(a[1:2])
[2]
>>> print(b[2:])
cdef
>>> print(a[::-1])
[4, 3, 2, 1]
>>> print(b[::-1])
fedcba
若非追求语法细节的“老鸟”,这段代码的作用恐怕难以一眼看出。实际上,为了体现更Pythonic的代码风格,应充分利用Python库中的reversed()函数。
>>> print(list(reversed(a)))
[4, 3, 2, 1]
>>> print(list(reversed(b)))
['f', 'e', 'd', 'c', 'b', 'a']
1 通过列表切片方式复制列表:
1.1 列表复制
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
print("My favorite foods are:")
print(my_foods)
print("\nMy friend's favorite foods are:")
print(friend_foods)
输出:
My favorite foods are: ['pizza', 'falafel', 'carrot cake'] My friend's favorite foods are: ['pizza', 'falafel', 'carrot cake']
1.2 验证确实实现了两个列表
my_foods.append('cannoli')
friend_foods.append('ice cream')
print("My favorite foods are:")
print(my_foods)
print("\nMy friend's favorite foods are:")
print(friend_foods)
输出:
My favorite foods are: ['pizza', 'falafel', 'carrot cake', 'cannoli'] My friend's favorite foods are: ['pizza', 'falafel', 'carrot cake', 'ice cream']
可以看出,通过切片方式复制列表,结果是生成了两个独立的列表。
2 通过简单赋值方式复制列表:
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods
my_foods.append('cannoli')
friend_foods.append('ice cream')
print("My favorite foods are:")
print(my_foods)
print("\nMy friend's favorite foods are:")
print(friend_foods)
输出:
My favorite foods are: ['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream'] My friend's favorite foods are: ['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
可以看出两个列表内容相同,这并非我们期望的结果。
此例说明了Python列表是链式存储结构,而非顺序存储。
a=[1,2,3,4]
for i in range(len(a)):
print(id(a[i]))
a[1]=100
print("----------")
for i in range(len(a)):
print(id(a[i]))
输出结果:
4471499232 4471499264 4471499296 4471499328 ---------- 4471499232 4471502400 4471499296 4471499328
Python列表函数与方法的操作对象不仅可以是字符串,也可以是列表。
list1 = ["Googl",'Jb51',2006,2020]
list2 = [1,2,3,4,5,6]
list2.append(list1)
print ("list2:",list2)
输出结果如下:
list2: [1, 2, 3, 4, 5, 6, ['Googl', 'Jb51', 2006, 2020]]
简单理解:Python在操作对象时,会根据对象自身的定义执行操作。此处list1被定义为列表,因此list.append(obj)在操作list1时表现为列表追加。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













