python 数据类型之列表

列表

容器型数据类型

即是可以一个数据内可存放多个其他数据的数据类型,像是个能装东西的容器。包括列表,元组,集合,字典等数据类型。

列表 (list)

定义

在Python中,列表是由一系元素按特定顺序构成的数据序列,这样就意味着定义一个列表类型的变量,可以保存多个数据,而且允许有重复的数据。跟上一课我们讲到的字符串类型一样,列表也是一种结构化的、非标量类型,操作一个列表类型的变量,除了可以使用运算符还可以使用它的方法。

列表的创建方法

那么如何创建一个列表呢,有如下4种方法:

  1. 最基本最简单的方法,和c语言定义数组一样,列表名 = [] ,[]内写列表中的元素,逗号分隔,最后一个元素后也可以写逗号。且可以使用 * 创建重复元素的列表。例如:

    list1=[0]*5         # 结果是[0,0,0,0,0]
  2. 循环配合append()函数或是insert()函数或是使用列表的加运算或是input()这种输入函数创建列表。append函数是添加元素在列表末尾,inset函数可以指定插入位置。例如:

    list1=[]
    for i in range(5):
        list1.append(i)
        # list1.insert(i,i)    # 默认前面的参数是想要插入位数,后面的是插入的元素
        # list1+=[i]
    ​
    #  结果都是[0, 1, 2, 3, 4]
    # 将循环体内的 i  改为int(input(f'请输入第{i+1}个元素'))    (insert中只改右边的)
    # 即可手动输入列表中每个元素
  3. 列表的生成式 列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。例如:

list1 = [x for x in range(1, 10)]
print(list1)    # 结果 [1, 2, 3, 4, 5, 6, 7, 8, 9]

这种方式创建列表,几乎可以取代第二种创建方式,除非你要使用input手动输入每个元素,否则建议使用这种方式创建列表,不仅代码少了,而且生成式拥有更好的性能,建议用生成式语法来创建列表

  1. 使用list()函数将数据转换成列表类型,例如:

    a='1,234,567,89'
    list1=list(map(int,a.split(',')))
    print(list1)                 #[1, 234, 567, 89]
    ​
    list2=list(range(4))           # [0, 1, 2, 3]       
    print(list2)
    ​
    list3=list(zip(list1,list2))   #  [(1, 0), (234, 1), (567, 2), (89, 3)]
    print(list3)

    除了可以转换这些数据,list还可以转换后面讲的元组,集合,字典(默认转 键,加.value 取值)等数据类型

列表的运算

列表的运算类似于字符串之间的运算,具体如下例说明

list1 = [12, 56, 42, 31, 45, 68]
list2 = [16, 32, 46, 25]
​
# 列表的拼接
list3 = list1 + list2
print(list3)  # [12,56,42,31,45,68, 16,32,46,25]
​
# 列表的重复
list4 = ['hello'] * 3
print(list4)  # ['hello', 'hello', 'hello']
​
# 列表的成员运算
print(100 in list3)  # False
print('hello' in list4)  # True
​
# 获取列表的长度(元素个数)
size = len(list3)
print(size)  # 10
​
# 列表的索引
print(list3[0], list3[-size])  # 12 12
list3[-1] = 100
print(list3[size - 1], list3[-1])  # 100 100
​
# 列表的切片
print(list3[:5])  # [12, 56, 42, 31, 45]
print(list3[4:])  # [45, 68, 16, 32, 46, 100]
print(list3[-5:-7:-1])  # [68, 45]
print(list3[::-2])  # [100, 32, 68, 31, 56]
​
# 列表的比较运算
list5 = [1, 2, 3, 4]
list6 = list(range(1, 5))
# 两个列表比较相等性比的是对应索引位置上的元素是否相等(默认比较第一个元素,相同则依次往后)
print(list5 == list6)  # True
list7 = [3, 2, 1]
# 两个列表比较大小比的是对应索引位置上的元素的大小(默认比较第一个元素,相同则依次往后)
print(list5 <= list7)  # True

要注意索引运算时不能越界,否则会报错,而切片操作则无需担心越界,越界也不会报错,只会取能取到的,如果范围内没有元素则返回空列表。

列表元素的遍历

列表大体有如下三三种遍历方法,一般都是使用for循环

 a=[range(8)]
 for i in a:
     print(i,end=' ')    #只读遍历
 
 for i in range(len(a)):   #可以更改
     print(a[i],end=' ')
​
 for i, x in enumerate(a):  #同时获取序号
     print(i+1,x)
​

第一种是循环变量依次等于变量中的每个元素以此遍历,好处是简单,不过不能获取元素序号,无法对元素进行更改;第二种就是循环变量等于列表的索引,并使用索引进行遍历,这种方法可以更改列表的元素,也可以获取列表的序号;不过可以更改有时候也不是优点,所以也可以使用enumerate()函数获取列表的索引与值,然后进行遍历。

列表的常用方法

列表有非常多的方法函数,下面简单介绍常用的几种

  • 首先是之前说过的添加元素用的 append与insert两个,append是在列表最后加入元素,insert则可以在列表任意位置插入元素。例子可以参考定义方法2

  • 有添加自然有删除,删除有以下几种方法

list1 = [12, 56, 11, 55, 32, 87]
​
# 删除指定的元素,如果多个一样的值只删除第一个
list1.remove(56)
print(list1)  # [12, 11, 55, 32, 87]
​
# 删除指定索引位置的元素,如果内容是空则删除最后一个
list1.pop(0)
del list1[len(list1) - 1]
print(list1)  # [11, 55, 32]
​
# 清空列表中的元素
list1.clear()
print(list1)  # []

第一种方法是remove方法,删除指定值的元素;第二种方法是按索引删除,有两种命令可以完成这一操作,分别是pip与del,两个命令使用方式略有不同,结果是一样的,不过pip会返回删除的元素,比如a=list1.pip(1)会在删除索引为1的元素同时把该元素赋值给a,del则不会,del的性能略优。

  • 还有查找元素索引以及元素计数的方法 index 与count

list1 = [12, 12, 11, 12, 32, 87]
print(list1.index(12))    # 查找元素,找到第一个就返回索引
print(list1.index(12, 1))    # 可设置从哪里开始找与找到哪里为止
print(list1.index(12, 3, 5))
​
print(list1.count(12))    # 计数一共有几个该元素
​

需要注意的是,index如果找不到元素会报错

  • 元素排序与反转 使用sort与reverse

list1 = [12, 56, 11, 55, 32, 87]
list1.sort()  # 排序
print(list1)     # [11, 12, 32, 55, 56, 87]
​
list1.reverse() # 反转
print(list1)    #[87, 56, 55, 32, 12, 11]
​
print(list1[::-1])   # 切片反转,不会改变原列表
        #[11, 12, 32, 55, 56, 87]

也可以使用切片操作的反转后 赋值给原列表

列表的嵌套

列表中不止可以放 各种字符与字符串,还可以放列表甚至后面说的元组,集合等等类型的数据,那么自然就可以实现列表中放列表,列表里面的列表还是列表的嵌套操作。这样的列表我们可以用于模拟多维数组或是矩阵。

但要特别注意不能用如下方式创建嵌套列表

cores = [[0] * 3] * 5
print(cores)    # [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
#否则就会导致如下后果
cores[0][0] = 95
print(cores)    # [[95, 0, 0], [95, 0, 0], [95, 0, 0], [95, 0, 0], [95, 0, 0]]
​
#正确的应该这样创建
scores = [[0] * 3 for _ in range(5)]
scores[0][0] = 95
print(scores)    # [[95, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

原因和计算机数据存放有关,我就不多解释了,对此有兴趣的小伙伴可以去Python Tutor网站使用可视化运行上述代码查看。

小练习

  1. 手动输入三数后按从大到小顺序输出。(最好不要使用sort,尝试自己排序,最好最后再去了解一下经典的排序算法,例如冒泡,选择,插入等等。)

  2. 随机10个数(自选范围即可),输出其中第二大的数。

  3. 与机器玩火柴游戏,有21根火柴,人和机器轮流拿,每次拿1-4根,拿到最后一根的输,机器后手,保证机器赢。

拓展:可以思考一下第三题的变量,火柴数,每次拿的最大最小数,先后手,甚至最后一根的输赢判定,对游戏结果的影响。

  1. 写个斗地主发牌的程序,并显示每个玩家的手牌结果。

tips: 思考代码有没有优化空间,注意有没有使用上嵌套列表

  1. 尝试几种简单的排序,冒泡,选择,插入,最好再尝试他们的升级,冒泡的升级搅拌(鸡尾酒),插入的升级中插(折半插入),计数也可以了解一下,如果仍有余力可考虑尝试希尔、归并、快排,其他的排序算法如果有兴趣也可以自行了解,可以去 十大经典排序算法 了解。

    tips: 冒泡就是,n个元素按顺序两两比较大小,如果大于(小于)就交换,直到一轮过去没有交换或n轮过去则排好了;选择则是每轮选出最小(大)的放在列表一端,然后在剩下元素中重复这样操作,就排序完成了;插入则是从第二个元素开始,每个元素和前一个元素比较,如果大于(小于)则将元素再往前比较,直到合适的位置插入,重复操作到最后一个元素就排好了。

    搅拌则是,要求冒泡时,一轮从左往右冒泡,一轮从右往左冒泡,这样可以略微提高代码效率,让代码有更高机会提前结束,特别是应对一些就快排好序的数列时,这样的冒泡是最快的。

    中插则是在插入时第一次和前一个比较后,如果大于(小于)就往前一半的位置插入,插入后和前后比较,大于(小于)前面则往前继续折半插入,小于(大于)后面则往后折半插入,直到合适位置然后继续下一个元素,直到最后一个元素插入完毕,折半插入是简单排序算法中平均性能最好的了。

    计数排序则是和数据个数与数据范围相关,建立一个整个范围的列表,然后将每个数据加入这个列表,再把这些数据拿出来就是顺序的了。

  2. 自定义一个列表有重复元素的列表(可以考虑随机20个10以内的整数),删除其中重复元素。

  3. 自定义一个列表有重复元素的列表,找出其中重复最多的元素。

  4. 有一个已经排好序的放整数的列表(数字从小到大),输入要查找的数据,如果在列表中找到该数据,输出该数据在列表的下标(索引),否则输出“找不到该数据”(要求使用折半查找,即一开始找中间,如果不是则比较大小,大则往右半继续折半,小则往做,重复操作,直到找到为止)

  5. (难度较高,不用勉强)有一个放整数的列表,其中有一个整数出现次数超过了半数以上,请找出该元素(要求时间复杂度不能大于n,也就是不是有两重甚至以上的循环,count,sort(直接就是二重循环,不能使用)等函数也算循环)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值