学习python(五)

本文详细介绍了Python中的列表,包括列表的介绍、常用操作如通过下标访问和修改值、连接和复制、切片、删除值,以及一些重要函数如index()、append()、remove()和sort()。此外,还探讨了列表的引用概念、浅拷贝与深拷贝的差异,并通过实例展示了如何使用这些知识解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

列表

列表的介绍

列表是python中的一种数据类型,一般的形式是这样的:

>>>fruit = ['apple','banana','pear']
>>>fruit
>>>['apple', 'banana', 'pear']
>>> number = [1,2,3,4]
>>> number
[1, 2, 3, 4]
>>> lists = ['apple','banana',2,4,['hello',-2,15.6]]
>>> lists
['apple', 'banana', 2, 4, ['hello', -2, 15.6]]

列表一般是使用一对[]将数据包起来,[]内的数据可以是整数,浮点数,字符串,一个新的列表也可以是各种类型混合起来,数据之间以逗号隔开.定义一个列表和定义一个变量的写法一样,需要变量名,赋值符号,列表的值(如上述代码所示)

列表的一些常用操作

通过下标取得列表中的单值

一维列表:

['apple', 'banana', 'pear', 10, 25.5]
>>> fruit[0]
'apple'
>>> fruit[3]
10

首先要说的一点就是,列表的下标是从0开始的.可以看到,列表中的每个值都有一个下标,通过下标就可以取到列表中的任何一个值,这个操作和c语言的数组很相似.
二维列表:

>>> lis = [['hello', -2, 15.6],[6,8,10]]
>>> lis[0][2]
15.6
>>> lis[0][1]
-2
>>> lis[1][1]
8
>>> lis[1][2]
10

列表lis中的值是由两个列表构成,要想取得具体的值就需要先取得第一层列表的下标,再根据第一层列表的下标取得具体的值.三维以及多维列表的取值和二维列表的取值思路相同,都是通过下标一层一层地取.

还有一个小的操作:

fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit[-1]
25.5
>>> fruit[-2]
10
>>> fruit[-3]
'pear'

下标为负的时候,-1代表列表的倒数第一个值,-2代表倒数第二个值,-3代表倒数第三个值,以此类推.

通过下标改变列表的值

>>> fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit[0] = 'grape'
>>> fruit
['grape', 'banana', 'pear', 10, 25.5]
>>> fruit[2] = 12 
>>> fruit
['grape', 'banana', 12, 10, 25.5]
>>> fruit[3] = 'peach' 
>>> fruit
['grape', 'banana', 12, 'peach', 25.5]

通过列表的下标就可以直接赋值覆盖列表中该位置的值.

列表的连接和复制

>>> test1 = ['A','B','C','D']
>>> test2 = ['E','F','G','H']
>>> test1 + test2
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']

这样就完成了一次列表的连接操作,当然,数字与数字,数字与字符只要是列表都可以进行连接.
列表的复制也很简单:

>>> test1 * 3
['A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B', 'C', 'D']

列表的切片

这个操作很好用,也很简单,在数据分析中经常用到:
首先要说明的是python列表中的值的下标是从0开始的,并且python中大部分求范围的操作一般按照左闭右开这样的原则来取值.

>>> fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit[0:2]
['apple', 'banana']
>>> fruit[2:4]
['pear', 10]
>>> fruit[0:3]
['apple', 'banana', 'pear']

可以看到,[]内的数字就代表了我们要取的列表中值下标的范围.取0–2的值代表了下标为0的值和下标为1的值并不包括下标为2的值.
还可以有这样的操作:

>>> fruit[:]
['apple', 'banana', 'pear', 10, 25.5]
>>> fruit[:4]
['apple', 'banana', 'pear', 10]
>>> fruit[:3]
['apple', 'banana', 'pear']
>>> fruit[2:]
['pear', 10, 25.5]
>>> fruit[4:]
[25.5]

可以看到[:]代表了取整个列表中的值,[:4]代表了从头开始取一直取到下标为3的值为止,[2:]则代表了从下标为2的值开始取到列表末尾.当然这样的操作也同样遵循左闭右开的原则,不信可以仔细数一数.
这种操作在使用python做数据分析时很常用,一般我们拿到的原始数据肯定很多,有些数据属于没用的数据,我们这时候就可以利用列表切片将有用的数据拿出来,再通过列表的连接凑成一组没有冗余的数据列表.

删除列表中的值

python的列表为我们考虑地很周全,既然已经有了增加,修改和查看操作那怎么能没有删除操作呢?
使用del关键字就可以实现根据列表的下标删除列表中的值:

>>> fruit = ['grape', 'banana', 12, 'peach', 25.5]
>>> del fruit[0]
>>> fruit
['banana', 12, 'peach', 25.5]
>>> del fruit[0:2]
>>> fruit
['peach', 25.5]

可以看到,我们可以通过单个下标来删除列表中的一个值,也可以使用切片的方式切掉列表中的一块儿内容.

使用列表进行一些操作

循环中的列表:
如果我们需要输出0,1,2,3,4通常可以这样操作:

for i in range(0,5)
    print(i)

也可以这样写:

for i in [0,1,2,3,4]
    print(i)

结果相同:

0
1
2
3
4

in和not in
这个常用于一些True或False的判断中.

fruit = ['apple','banana','grape']
name = input('please input fruit name:')
if name not in fruit:
    print('There have not ' + name + ' in list')
elif name in fruit:
    print(name + ' in list')

终端输入python3 test.py来运行脚本,样例输出:

please input fruit name:apple
apple in list
please input fruit name:peach
There have not peach in list

while循环的判断条件里也可以使用(我目前知道的也就在这两个地方来使用这个知识点)

还有一个就是多重赋值操作,这个很简单,两行代码就能说明白:

>>> color,size,texture = ['red','big','sweet']
>>> color
'red'
>>> size
'big'
>>> texture
'sweet'

要注意的就是列表中值的个数必须和赋给值的变量个数保持一致不然程序就会报错.

列表中的几个重要的函数

index()函数

我们可以通过index()函数来根据列表中的值取到该值在列表中的位置:

>>> fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit.index('banana')
1
>>> fruit.index(10)
3

append()函数和insert()函数

这两个函数都是向列表中添加值,观察一下它们有什么不同的地方:
append():

>>> fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit.append('peach')
>>> fruit.append('grape')
>>> fruit
['apple', 'banana', 'pear', 10, 25.5, 'peach', 'grape']

insert():

>>> fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit.insert(1,'peach')
>>> fruit
['apple', 'peach', 'banana', 'pear', 10, 25.5]
>>> fruit.insert(3,'grape')
>>> fruit
['apple', 'peach', 'banana', 'grape', 'pear', 10, 25.5]

这样看来两个函数的区别就明显多了.append()只能将值添加在列表的尾部,而insert()函数则可以将值添加在列表中的任何位置.

remove()函数

顾名思义,删除列表中的元素,还记得del关键字吗?看看有什么区别:

>>> fruit = ['apple', 'banana', 'pear', 10, 25.5]
>>> fruit.remove('apple')
>>> fruit
['banana', 'pear', 10, 25.5]
>>> fruit.remove(10)
>>> fruit
['banana', 'pear', 25.5]

明显remove()函数是根据列表的值来删除内容的,而我们需要使用下标来删除列表中的值时del关键字则更好用一些.

sort()函数

对于数字的排序:

>>> example = [5,4,9,-1,8.5]
>>> example.sort()
>>> example
[-1, 4, 5, 8.5, 9]

对于字符串的排序是根据字符串首字母的ascll码来排的:

>>> example = ['grape','banana','apple','peach']
>>> example.sort()
>>> example
['apple', 'banana', 'grape', 'peach']

sort()函数默认是升序排序,也可以通过关键字reverse = True来改变排序方式为降序排序:

>>> example = [5,4,9,-1,8.5]
>>> example,sort(reverse = True)
>>> example
[9, 8.5, 5, 4, -1]

对于排序还有一个小的知识,我记得之前我去一家公司面试python开发时,面试官在最后问我了一个问题,他说python中的sort()函数是用来排序的那你有没有了解过sort()函数具体是使用的哪种排序算法呢?我当时一脸MB.回来之后我就查阅了相关的资料,发现sort()函数的排序算法是一个叫Timsort的排序算法,我就顺手写了几个demo测试了一下这个算法(之前考研的时候研究数据结构的算法时,把书上的10好几种算法研究了个遍,也留下了好多好多测试样例)我发现这个算法真的很好用,以前喜欢用快排现在就抓着Timsort用了,有兴趣的朋友可以了解了解Timsort原理.强烈安利好吧.

一个非常非常非常重要的概念–引用

那就先从列表,元组,字符串说起吧.
元组和列表在形式上十分的相似,它是这样定义的:

>>> lis = (1,2,3,4)
>>> type(lis)#查看lis的数据类型
<class 'tuple'>

列表是使用[]将数据包裹起来的,而元组是使用().元组与列表最大的不同在于元组中的值一旦写好之后就不能改变.这个改变的意思是不能对元组进行插入和删除操作,当然索引元组中的元素和连接两个元组的操作是可以的.
字符串和列表的区别也一样:

>>> str = 'Hello Wold'
>>> str[1]
'e'
>>> str[3]
'l'
>>> str1 = 'ni hao shi jie'
>>> str + str1
'Hello Woldni hao shi jie'

所以在python中列表属于可变的数据类型,元组和字符串则属于不可变的数据类型.
元组和列表在形式上如此的相似,那么在python中是允许相互转换的,同样也允许字符串转换成列表形式:

#元组转换为列表
>>> tuple = (1,2,3,4)
>>> list(tuple)
[1, 2, 3, 4]
#列表转换成元组
>>>lis = [5,6,7,8]
>>>tuple(lis)
>>>(5,6,7,8)
#字符串转换成元组
>>> str = 'HelloWorld'
>>> list(str)
['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']

其实说了元组,字符串这么多主要就是为了说可变和不可变的数据类型,说实话一开始我也觉得这个东西没多大用处,不管可变不可变只要能用就行.列表多好,既能增加又能删除.但是表面上看起来好的东西其实也是存在一些问题的,而且深入理解引用的概念有利于更加深入了解python内部列表的机制.请接着往下看:

>>> lis1 = [0,1,2,3,4,5]
>>> lis2 = lis1
>>> lis2
[0,1,2,3,4,5]
>>> lis1[1] = 'hello'
>>> lis1
[0,'hello',2,3,4,5]
>>> lis2
[0,'hello',,2,3,4,5]

仔细看看上述的代码都干了什么,看完是不是觉得很奇怪,我只是将lis1的值赋给了lis2,但是我在后面改变lis1的值后lis的值也跟着改变了.这是怎么回事呢?
其实是在python中我们在代码里写着将列表赋给另一个变量其实并不是把列表的值赋给它,而是把列表的引用赋给了它.
因为图不是很好画,我就直接使用书上的图片了,以下两张图取自《Python编程快速上手—让繁琐工作自动化》page:76(如果有侵权的行为请联系我,我会立即删除)
在这里插入图片描述
在这里插入图片描述
可以看到lis1在赋给lis2值的时候只是将lis1的ID这一串数字赋给了lis2(也就是将lis1的引用赋给了lis2),实际上此时的lis1和lis2是共用一个列表的,当我们修改lis1的值时,在python内部是通过ID来找到真正的列表的位置再修改它的值,所以修改后lis2的值也发生了同样的变化.同样的,我们修改lis2的值lis1也会发生一样的变化,原理是一样的.

浅拷贝和深拷贝
如果是一维的列表深拷贝和浅拷贝没什么区别,但是如果是列表中的值有列表的话那么就是有区别的了,在这里只介绍copy和deepcopy的区别.我们在之后需要使用一个操作import copy它的意思是导入一个模块,这个模块里有相应的深拷贝和浅拷贝的方法,我们直接调用就可以实现功能了,很方便.
浅拷贝:

>>> lis = [1,2,3,['a','b']]
>>> import copy
>>> lis1 = copy.copy(lis)
>>> lis1
[1, 2, 3, ['a', 'b']]
>>> lis.append(5)
>>> lis
[1, 2, 3, ['a', 'b'], 5]
>>> lis1
[1, 2, 3, ['a', 'b']]
>>> lis[3].append('cccccc')
>>> lis
[1, 2, 3, ['a', 'b', 'cccccc'], 5]
>>> lis1
[1, 2, 3, ['a', 'b', 'cccccc']]

可以看到,在上述程序的第3行浅拷贝了一个lis1,接下来在第6行在lis的末尾添加了一个5后,我们发现浅拷贝后的lis1并没有发生改变.难道是浅拷贝的概念错了?别着急接着往下看,第11行我们向lis中的列表里添加了一个值,最后终于发现lis1中的值也跟着发生了变化,这也是浅拷贝和深拷贝的区别.
深拷贝:

>>> lis = [1,2,3,['a','b']]
>>> import copy
>>> lis2 = copy.deepcopy(lis)
>>> lis2
[1, 2, 3, ['a', 'b']]
>>> lis[3].append('cccccc')
>>> lis
[1, 2, 3, ['a', 'b', 'cccccc']]
>>> lis2
[1, 2, 3, ['a', 'b']]

程序第6行我们对lis中的列表添加一串字符,再看最后四行,lis中的值发生了改变而lis2中的值却依旧没变.
专业术语的解释是:
浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变
深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变

两个简单的实例

第一个题目取自《Python编程快速上手—让繁琐工作自动化》page:79:逗号代码:
假定有下面这样的列表:spam = [‘apples’, ‘bananas’, ‘tofu’, ‘cats’],编写一个函数,它以一个列表值作为参数,返回一个字符串。该字符串包含所有表项,表项之间以逗号和空格分隔,并在最后一个表项之前插入 and。例如,将前面的 spam 列表传递给函数,将返回’apples, bananas, tofu, and cats’。但你的函数应该能够处理传递给它的任何列表。
代码如下:

def Addelem(lis):
    str1 = ''
    for i in range(len(lis)):
        str1 = str1 + str(lis[i]) + ','
    str1 = str1 + 'and' + str(lis[-1])
    return str1
spam = ['apples','bananas','tofu','cats']
str2 = Addelem(spam)     
print(str2)

结果输出:

apples,bananas,tofu,the cats

第二个题目取自《Python编程快速上手—让繁琐工作自动化》page:79:字符图网格:
假定有一个列表的列表,内层列表的每个值都是包含一个字符的字符串,像这样:
在这里插入图片描述
你可以认为 grid[x][y]是一幅“图”在 x、y 坐标处的字符,该图由文本字符组成。原点(0, 0)在左上角,向右 x 坐标增加,向下 y 坐标增加。复制前面的网格值,编写代码用它打印出图像。
在这里插入图片描述
代码如下:

grid = [ ['.', '.', '.', '.', '.','.'],
         ['.', '0', '0', '.', '.','.'],
         ['0', '0', '0', '0', '.','.'],
         ['0', '0', '0', '0', '0','.'],
         ['.', '0', '0', '0', '0','0'],
         ['0', '0', '0', '0', '0','.'],
         ['0', '0', '0', '0', '.','.'],
         ['.', '0', '0', '.', '.','.'],
         ['.', '.', '.', '.', '.','.']]
for i in range(0,6):
    for j in range(0,9):
        print(grid[j][i],end = '')
    print()

结果输出:

..00.00..
.0000000.
.0000000.
..00000..
...000...
....0....

今天的内容有点多,但是都很重要.
本文内容主要参考《Python编程快速上手—让繁琐工作自动化》第四章内容,如果有什么错误的地方欢迎指正.

.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值