python list数据结构_Python 6-1.内置数据结构之list(基础篇)

-常见内置数据结构-

list 列表

set 集合

dict 字典

tuple 元祖

-本章大纲-

list(列表):

一组由顺序的数据的组合

创建列表

有值列表

无值列表(空列表)

使用list创建列表

修改列表值

列表常用操作

访问列表

使用下标操作(索引),大部分语言索引都是从0开始

列表位置从0开始

语法: list[val]

分片操作(截取操作)

从列表里截取任意一段

语法: list[开始:结束]

del(删除命令)

列表的连接

使用乘加来对列表操作

列表成员资格运算

列表的遍历使用

使用for和while来遍历,对比过程

双层列表循环

列表内涵:list content

关于列表的常用函数

len(list)获取列表长度

mxn(list)求列表最大值

min(list)求列表最小值

list(str)把字符串拆分成字符并存入列表里面

list.append(val)在列表尾部追加内容

list.insert(index,val)在指定下标前面插入内容

list.pop(index) 取出指定下标的值

list.remove(index.max)删除指定下标的内容

list.clear()清空列表里面的内容

list.reverse()f翻转列表类容,原地翻转地址不变

list.extend(list2)拓展列表,把一个列表拼接到另一个后面

list.count()查找列表中相同指定值或元素的数量

list.copy()浅拷贝

copy.deepcopy(list)深拷贝

空列表案例

l1 =[]print(type(l1))print(l1)

结果如下:

[]

带值列表案例

l2 = ["1","2","lalla","啦啦啦"]print(type(l2))print(l2)

结果如下:

['1', '2', 'lalla', '啦啦啦']

使用list()来创建空列表

l3 =list()print(type(l3))print(l3)

结果如下:

[]

修改列表内容

l = [1,2,3,4,5]print(l)#修改前

l[1] = 100

print(l[:])#修改后

结果如下:

[1, 2, 3, 4, 5]

[1, 100, 3, 4, 5]

修改一部分列表的内容

l = [1,2,3,4,5]print(l)#修改前

l[1:3] = 100,200

print(l)#修改后

结果如下:

[1, 2, 3, 4, 5]

[1, 100, 200, 4, 5]

-列表常用操作-

访问列表

使用下标操作(索引),大部分语言索引都是从0开始

列表位置从0开始

语法: list[val]

分片操作(截取操作)

从列表里截取任意一段

语法: list[开始:结束]

del(删除命令)

列表的连接

使用乘加来对列表操作

列表成员资格运算

列表的遍历使用

使用for和while来遍历,对比过程

双层列表循环

列表内涵:list content

关于列表的常用函数

下标访问列表案例

l = [1,2,4,123,3]print(l[3]) #下标从0开始,所以截取的下标3为第四个

结果如下:

123

-分片操作-

注意截取范围,一般来说有开始和结束两个下标值都是包括左不包括右

案例如下

l = [1,2,4,123,3]print(l[1:4]) #截取从第二个到第四个

结果如下:

[2, 4, 123]

下标值可以为空,如果不屑,左边下标值默认为0,右边下标值默认为最大数加一,也就是说截取到最后一位

注意最终打印的结果

左右下标完全不写

l = [1,2,4,123,3]print(l[:])

结果如下:

[1, 2, 4, 123, 3]

只写左边下标

l = [1,2,4,123,3]print(l[1:])

结果如下:

[2, 4, 123, 3]

只写右边下标

l = [1,2,4,123,3]print(l[:4])

结果如下:

[1, 2, 4, 123]

分片操作可以控制增长幅度,默认增长幅度为1

l = [1,2,4,123,3]print(l[1:6:1])

结果如下:

[2, 4, 123, 3]

打印从下标1到4的数字,每次遍历中间隔开一个

l = [1,2,4,123,3]print(l[1:4:2])

结果如下:

[2, 123]

下标索引可以超出范围,不过超出后不会提示错误并且不考虑多余下标内容

l = [1,2,4,123,3]print(l[1:100])

结果如下:

[2, 4, 123, 3]

-下标值和增长幅度可以为负数-

当下标值为负数时,索引遍历的顺序就会相反,即从右到左

当下标值为负数时,列表里最后的内容下标为-1

分片操作 下标值为负,案例如下

无论下标值是否为负,左边的下标值一定要比右边的下标值小

l = [1,2,4,123,3]print(l[-2:-4]) #执行结果为空

print(l[-4:-2])

结果如下:

[]

[2, 4]

如果分片的左边下标值一定要比右边下标值大,则增长幅度要使用负数

此案例为一个list直接正反颠覆提供了一种思路

l = [1,2,4,123,3]print(l[-2:-4:-1])

结果如下:

[123, 4]

-分片操作是生成一个新的list-

内置函数id,负责显示一个遍历或数据的唯一确定编码

id函数案例如下

a = 100b= 200

两个变量不能通过值来对其身份判断

可以通过id函数获取编码进行对比

print(id(a))print(id(b))

结果如下:

140723906273408

140723906276608

我们对比c和b的编码,可以看出c和b并不是同一身份,而a和c确实统一身份,这就涉及到传值和传址

c =aprint(id(c))

结果如下:

140723906273408

这里更改了a的值,按照逻辑,c的值也应该更改,但是我们看编码,c的值并没有发生变化,这就是顺序结构的影响,c所接收的值是还没更改的a的值,再a更改过后,c并未接收到指令需要再次更改

a = 101

print(id(a))print(id(c))

结果如下:

140723906273440

140723906273408

当c再次接收指令需要更改值时的编码

c =aprint(id(a))print(id(c))print(id(a)==id(c)) #返回的结果为true

结果如下:

140723906273440

140723906273440True

使用id内置函数来判断截取的list是否是新生成的列表

l = [3,2,1,23,3]

ll= l[:] #通过截取方式赋值

lll = l #直接进行赋值

对比三者的编码

print(id(l))print(id(ll))print(id(lll)) #很明显,直接赋值的编码跟原来的list完全一致

结果如下:

1425021100616

1425021100680

1425021100616

我们再次通过修改列表的内容,来证实

l[1] = 100

print(l)print(ll)print(lll)

结果如下:

[3, 100, 1, 23, 3]

[3, 2, 1, 23, 3]

[3, 100, 1, 23, 3]

通过结果可以看出截取的list并未发生任何变化,反之直接赋值的list就跟原本list发生了相同的变化,这又是传值和传址的问题

-del 删除命令-

语法:

del 列表名称[需要删除内容的下标]

删除案例如下:

a = [1,2,3,4,5]del a[2]print(a)

结果如下:

[1, 2, 4, 5]

利用id内置函数查看删除过后的list是否还是原来的列表,还是系统给重新生成了一个

a = [1,2,3,4,5]print(id(a)) #删除前

del a[2]print(id(a)) #删除后

结果如下:

1617250837064

1617250837064

从id给的编码看得出来,并没有不同,证明删除的内容是直接从list里删除,而不是将不需要删除的内容重新放置到一个新的list里面

del删除了一个变量之后不能再继续使用该变量

a = [1,2,3,4,5]delaprint(a) #删除列表类型的变量

b= 1

delbprint(b) #删除普通变量

结果如下:

Traceback (most recent call last):

File"D:/图灵/2.基础语法/测试.py", line 3, in

print(a) #删除列表类型的变量

NameError: name 'a' is not defined

无论删除任何类型的变量,后面都不能再继续使用该变量

-列表的连接使用-

使用算术运算符进行链接

使用加号连接两个列表

a = [1,2,3,4,5]

b= [6,7,8,9,10]

c= a +bprint(c)

结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

使用乘号操作列表

a = [1,2,3,4,5]

b= a * 3

print(b)

结果如下:

[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

得到的值相当于n和相同的列表相加

列表成员资格运算

使用in成员运算符进行操作(关于in函数前面"表达式章节有讲")

使用in进行操作

a = [1,2,3,4,5]

b= 8

print(b in a) #返回值为布尔值

结果如下:

False

使用not in进行操作

a = [1,2,3,4,5]

b= 8

print(b not in a)

结果如下:

True

-列表的遍历-

for

while(凡是关于遍历的大都不推荐)

使用for进行遍历操作

案例如下

a = [1,2,3,4,5]for i ina:print(i) #通过遍历打印

#对比两种打印之后值的类型

print(type(i))print(a) #直接打印

print(type(a))

结果如下:

1

2

3

4

5

[1, 2, 3, 4, 5]

通过遍历打印和直接打印的最大区别是,前者把整个列表拆散,一个一个去访问里面的值然后进行打印,后者直接看作一个整体进行打印

我们可以看到遍历打印之后的值是int类型,而直接遍历的值为list类,看得出来拆分过后的值类型是按照原本它在列表时的类型进行输出

有个很有意思的东西,分享给大家,这是大拿老师分享给我们的

不常写python代码的程序员写的python代码是这样的

a = [1,2,3,4,5]for i in range(0,len(a)): #他们会把a(列表)看成一个值,把列表的内容获取之后存入range再通过for进行打印

print(a[i])

i+= 1

使用while循环访问list(麻烦死了=-=)

不推荐使用while遍历list

len(list,tuple,dict)=返回对象(字符、列表、元组等)长度或项目个数

a = [1,2,3,4,5]#定义index表示list的下标

index =0while index

index += 1 #让下标每遍历一次就进行下一个下标的遍历

结果如下:

1

2

3

4

5

-双层列表循环-

a = [["zhansan",12,"游戏"],["lisi",13,"游泳"],["wangwu",15,"篮球"]]

打印方法:每个列表有多少个值就用多少个变量进行带出

for k,v,w ina:print(k,"--",v,"--",w)

结果如下:

zhansan -- 12 --游戏

lisi-- 13 --游泳

wangwu-- 15 -- 篮球

循环变量的个数应该于列表解包出来的变量个数一致

a = [["zhansan",12,"游戏"],["lisi",13,"游泳"],["wangwu",15,"篮球",1,2,3,4,]]

打印方法:每个列表有多少个值就用多少个变量进行带出,否则就会出错

for k,v,w ina:print(k,"--",v,"--",w)

结果如下:

Traceback (most recent call last):

zhansan-- 12 --游戏

lisi-- 13 --游泳

File"D:/图灵/2.基础语法/测试.py", line 2, in

for k,v,w ina:

ValueError: too many values to unpack (expected3)

-列表内涵:list content-

通过简单方法创作列表

通过for遍历出来的值放置到一个新的列表里面来形成一个列表

a = [1,2,3,4]#通过list a 来创建新的list b

b = [i for i ina]print(a)print(b)#对比id编码是否相等

print(id(a))print(id(b))

结果如下:

[1, 2, 3, 4]

[1, 2, 3, 4]1651187802696

1651187802760

通过代码我们可以看出就算b列表的值是从a列表里面获得的,但是编码显示它们不是同一个变量

在生成新的列表时,使用乘号对列表值进行操作

案例条件:让b里面的所有值乘以10

a = [1,2,3,4,5]

b= [i*10 for i ina]print(a)print(b)

结果如下:

[1, 2, 3, 4, 5]

[10, 20, 30, 40, 50]

还可以通过算法将过滤的内容放置新列表

使用for i in range生成从1到34的列表a,将列表a里面的偶数生成一个列表b

a = [i for i in range(1,34)]

b= [r for r in a if r%2 ==0]print(a)print(b)

结果如下:

[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]

[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32]

列表生成式可以嵌套

a = [i for i in range(1,5)] #生成 list a

b = [i for i in range(100,500) if i % 100 == 0]

将a和b列表里面的值对应相加并且放置新列表c里面

n将a列表内容逐个遍历,m将b列表内容逐个遍历

c = [n+m for n in a for m inb]#分别打印a,b,c列表对比内容

print(a)print(b)print(c)

结果如下:

[1, 2, 3, 4]

[100, 200, 300, 400]

[101, 201, 301, 401, 102, 202, 302, 402, 103, 203, 303, 403, 104, 204, 304, 404]

将c里面的表达式详细版:案例如下

其实就是个嵌套循环

for n ina:for m inb:print(m+n,end=" ") #end是print内置函数的一个参数,规定空格,默认值end="\n"

help(print) #查看print的官方帮助文档,help(函数名) = 查看该函数的官方帮助文档

结果如下:

101 201 301 401 102 202 302 402 103 203 303 403 104 204 304 404Help on built-in function print inmodule builtins:print(...)print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream,orto sys.stdout by default.

Optional keyword arguments:

file: a file-like object (stream); defaults to the current sys.stdout.

sep: string inserted between values, default a space.

end: string appended after the last value, default a newline.

flush: whether to forcibly flush the stream.

-列表的常用函数-

len(list)获取列表长度

mxn(list)求列表最大值

min(list)求列表最小值

list(str)把字符串拆分成字符并存入列表里面

list.append(val)在列表尾部追加内容

list.insert(index,val)在指定下标前面插入内容

list.pop(index) 取出指定下标的值

list.remove(index.max)删除指定下标的内容

list.clear()清空列表里面的内容

list.reverse()f翻转列表类容,原地翻转地址不变

list.extend(list2)拓展列表,把一个列表拼接到另一个后面

list.count()查找列表中相同指定值或元素的数量

list.copy()浅拷贝

copy.deepcopy(list)深拷贝

求列表长度

len(list)获取列表长度

a = [x for x in range(1,100)]print(len(a))

结果如下:

99

求列表中最大值

mxn(list)求列表最大值

a = [x for x in range(1,100)]print(max(a))

结果如下:

99

求列表中最小值

min(list)求列表最小值

a = [x for x in range(1,100)]print(min(a))

结果如下:

1

如果获取列表最大值的类型为str,则选择字符最长的为最大值

a = ["a","ab","abc"]print(max(a))#min同理

print(min(a))

结果如下:

abc

a

list(str)把字符串拆分成字符并存入列表里面

s = "Baby, there's nothing holding me back"

print(list(s))

结果如下:

['B', 'a', 'b', 'y', ',', ' ', 't', 'h', 'e', 'r', 'e', "'", 's', ' ', 'n', 'o', 't', 'h', 'i', 'n', 'g', ' ', 'h', 'o', 'l', 'd', 'i', 'n', 'g', ' ', 'm', 'e', ' ', 'b', 'a', 'c', 'k']

把range产生的内容转化成list

list(range(start,stop))

print(list(range(1,10)))

结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

list.append(val)在列表尾部追加内容

a = [i for i in range(1,10)]print(a) #追加前

a.append(100)print(a) #追加后

结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

[1, 2, 3, 4, 5, 6, 7, 8, 9, 100]

list.insert(index,val)在指定下标前面插入内容

a = [i for i in range(1,10)]print(a)

a.insert(3,100) #在下标为3的前面插入一个内容

print(a)

结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

[1, 2, 3, 100, 4, 5, 6, 7, 8, 9]

删除

del 和 pop的区别,前者为直接删除,后者为取出

del删除,直接在列表里面删除

a = [i for i in range(1,10)]print(a)delaprint(a) #删除之后无法调用

结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

Traceback (most recent call last):

File"D:/图灵/2.基础语法/测试.py", line 4, in

print(a) #删除之后无法调用

NameError: name 'a' is not defined

pop则是从对应的下标位置取出一个元素,取出的元素为最后一个

a = [i for i in range(1,10)]print(a.pop())

结果如下:

9

list.remove(index.max)删除指定下标的内容

如果被指定要删除的值没在list中,则会报错

所以在使用remove时,最好使用先行判断

查看remove操作时直接从列表里面进行删除,还是将值取出来放置到一个新的list里面

a = [i for i in range(1,10)]print(id(a))#删除前

aa = 8 #指定一个值

if aa ina:

a.remove(aa)print(a)print(id(a))#删除后

结果如下:

2721021846088[1, 2, 3, 4, 5, 6, 7, 9]2721021846088

list.clear()清空列表里面的内容

使用clear来清空,我们可以看到列表还在,而且里面的地址也是一致的

a = [i for i in range(1,10)]print(a)print(id(a))

a.clear()print(a)print(id(a))

结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9]2428798329416[]2428798329416

如果不计较地址问题时,我们可以直接使用空的list去替换掉,但这时地址就不一致了

a =[]print(a)print(id(a))

结果如下:

[]2158892847240

list.reverse()f翻转列表类容,原地翻转地址不变

a = [1,2,3,4,5]print(a)#翻转前

print(id(a))

a.reverse()print(a)#翻转后

print(id(a))#翻转过后还是同一个列表

结果如下:

[1, 2, 3, 4, 5]2783136211528[5, 4, 3, 2, 1]2783136211528

list.extend(list2)拓展列表,把一个列表拼接到另一个后

a = [1,2,3,4]

b= [6,7,8,9,10]print(a) #拼接前

print(id(a))

a.extend(b)print(a)#拼接后

print(id(a))print(a+b) #使用拼接手法来拓展列表,能使拓展列表原来的地址保存,而直接相加来拓展,则会生成一个新的列表

print(id(a+b))

结果如下:

[1, 2, 3, 4]2219187266120[1, 2, 3, 4, 6, 7, 8, 9, 10]2219187266120[1, 2, 3, 4, 6, 7, 8, 9, 10, 6, 7, 8, 9, 10]2219216318920

list.count()查找列表中相同指定值或元素的数量

a = [1,2,3,3,4,2]print(a)print(a.count(2)) #列表中有两个2

结果如下:

[1, 2, 3, 3, 4, 2]2

copy:拷贝,此函数是浅拷贝

关于拷贝和直接赋值的区别

直接赋值案例:

a = [1,2,3,4,5]

b=aprint(id(a))print(id(b))

结果如下:

1296231391816

1296231391816

直接赋值的id是一致的,那就是说无论在何处修改修改a或b另一个都会发生改变

b[3] = 111

print(a)print(b)

结果如下:

[1, 2, 3, 111, 5]

[1, 2, 3, 111, 5]

拷贝案例

a = [1,2,3,4,5]

b=a.copy()print(id(a))print(id(b))

结果如下:

1312161292872

1312161292936

通过a拷贝的b列表里面的id与a列表完全不符合,这就可以在修改a或b时不会影响到另一个列表了

a[1] = 888

print(a)print(b)

结果如下:

[1, 888, 3, 4, 5]

[1, 2, 3, 4, 5]

浅拷贝和深拷贝的区别

copy函数只是个浅拷贝函数,只拷贝一层内容

a = [1,2,3,[1,2,3,4]]

b=a.copy()print(id(a))print(id(b))

结果如下:

2354867757704

2354868916552

这时使用id函数访问a列表里面的双层列表

print(id(a[3]))print(id(b[3]))

结果如下:

2869806391880

2869806391880

由此可见,浅拷贝无法拷贝双层列表里面的内容

我们通过修改来查看区别

修改双层列表内容

a[3][2] = 636

print(a)print(b)

结果如下:

[1, 2, 3, [1, 2, 636, 4]]

[1, 2, 3, [1, 2, 636, 4]]

修改列表内容

a[3][2] = 111

print(a)print(b)

结果如下:

[1, 2, 3, [1, 2, 111, 4]]

[1, 2, 3, [1, 2, 111, 4]]

只有双层列表里面的内容可以被修改

使用深拷贝来拷贝双层列表

引入copy库

importcopy

a= [1,2,3,[1,2,3,4]]

b=copy.deepcopy(a)print(a)print(id(a))print(b)print(id(b))

结果如下:

[1, 2, 3, [1, 2, 3, 4]]2427933269384[1, 2, 3, [1, 2, 3, 4]]2427933267848

再查看双层列表的id

print(id(a[3]))print(id(b[3]))

结果如下:

1724958056840

1724958057160

这时双层列表内容的id也发生了变化

通过改变a双层列表里面的内容来观察变化

a[3][2] = 666

print(a)print(b)

结果如下:

[1, 2, 3, [1, 2, 666, 4]]

[1, 2, 3, [1, 2, 3, 4]]

这时b列表的双层列表并没有发生变化,这就是浅拷贝和深拷贝的区别

关于传值和传址的区别

defint(n):

n+= 100

print(id(n))print(n)deflist(n):

n[2] = 100

print(id(n))print(n)returnNone

n1= 1n2= [1, 2, 3, 4, 5]print(n1)print(id(n1))

int(n1)print(n1)print(id(n1))print(n2)print(id(n2))

list(n2)print(n2)print(id(n2))

我们观察在调用函数前和调用函数后,int和list类型的两个变量编码的变化

结果如下:

1

140723906270240

140723906273440

101

1

140723906270240

[1, 2, 3, 4, 5]

2431234302536

2431234302536

[1, 2, 100, 4, 5]

[1, 2, 100, 4, 5]

2431234302536

我们可以看到两个函数,经过函数改变之后,函数局部打印和全局打印列表是一致的,反之int方面则不同

因为对于列表来说传入的参数为传址,所以在全局打印时访问的地址和局部的相同,则打印的内容也相同

而int传入的参数为传值,因为局部访问时访问的是参数的值,当全局访问时无法获得经过函数改之后参数的值,所以值没发生改变

文笔不好,仅供参考

要有错误或者有其他更多的见解,欢迎大家加我QQ384435742来交流

想第一时间看更新的文章,请关注,谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值