理论部分
练习部分
首先回顾下基本数据类型和容器数据类型。
基本数据类型 | 符号 |
---|---|
整形 |
|
浮点型 |
|
布尔型 |
|
容器数据类型 | 符号 |
---|---|
列表 |
|
元组 |
|
字典 |
|
集合 |
|
字符串 |
|
列表是有序集合,没有固定大小,能够保存任意数量任意类型的 Python 对象。
变量 = [元素1, 元素2, …, 元素n]
常规创建列表
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
print(x, type(x))
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
利用range创建列表
x = list(range(10, 1, -2))
print(x, type(x))
# [10, 8, 6, 4, 2]
利用推导式创建列表
x = [i ** 2 for i in range(1, 10)]
print(x, type(x))
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
x = [i for i in range(100) if (i % 2) != 0 and (i % 3) == 0]
print(x, type(x))
# [3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 87, 93, 99]
创建二维数组
多维列表创建原理为列表除最后一维的元素都为列表。(禁止套娃)
# 推导式方法
x = [[0 for col in range(3)] for row in range(4)]
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
x = [[0] * 3 for row in range(4)]
print(x, type(x))
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
由于list的元素可以是任何对象, 因此列表中保存的对象的指针。a是个列表,如[a] * 3 = [a, a, a],就是指针复制了3份,指向同一个a,一旦a的值发生改变,列表的结果也变了(二维以上才能做到,一维直接指向数值元素)。
a = [0]*3
ls = [a]*3
print(ls)
# [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
ls[0][1]= 1
print(ls)
# [[0, 1, 0], [0, 1, 0], [0, 1, 0]]
a[0] = 2
print(ls)
# [[2, 1, 0], [2, 1, 0], [2, 1, 0]]
a[0],a[1],a[2]=1,2,3
print(ls)
# [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
'''
-------------------错误示范----------------
'''
a = [1, 2, 3]
print(ls)
# [[2, 1, 0], [2, 1, 0], [2, 1, 0]]
ls[0] = [1, 2, 3]
print(ls)
# [[1, 2, 3], [2, 1, 0], [2, 1, 0]]
注意!!!
ls[0][1]
和a[0]
来进行改变a指向内存内的值,若需要全都更改,使用a[0],a[1],a[2]=1,2,3
实现。a = [1, 2, 3]
是不会对列表造成改变,这种操作会导致a指向别的内存地址,也就是说列表所对的地址还是a原先的地址,那里的值并没有发生改变。创建混合列表
列表不限制元素类型。
mix = [1, 'lsgo', 3.14, [1, 2, 3]]
print(mix) # [1, 'lsgo', 3.14, [1, 2, 3]]
创建空列表
empty = []
print(empty) # []
下面介绍列表的附加(append
, extend
)、插入(insert
)、删除 (remove
,pop
)等操作。
主要包括三个函数,list.append(obj)
、list.extend(seq)
和list.insert(index,obj)
。
list.append(obj)语句(追加)
在列表末尾添加新的对象,只接受一个参数,参数可以是任何数据类型,被追加的元素在 list 中保持着原结构类型。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.append('Thursday')
print(x)
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday']
list.extend(seq)语句(扩展)
在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)。
注意,extend()参数为seq,需要是个序列(容器类型),不能传入基本数据类型。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.extend(['Thursday', 'Sunday'])
print(x)
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Thursday', 'Sunday']
注意当参数为一个列表时,append和extend的区别。append是追加,extend是扩展(可以理解为两个列表拼接在一起)。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.append(['Thursday', 'Sunday'])
print(x)
# ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', ['Thursday', 'Sunday']]
append传入的列表保持原结构类型。
list.insert(index, obj) 在编号 index 位置前插入 obj(注意在index前)
注意是在index前插入,index从0开始。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
# 0 1 2 3 4
x.insert(2, 'Sunday')
print(x)
# ['Monday', 'Tuesday', 'Sunday', 'Wednesday', 'Thursday', 'Friday']
list.remove(obj) 移除列表中某个值的第一个匹配项,无返回值
obj参数为匹配值。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
x.remove('Monday')
print(x) # ['Tuesday', 'Wednesday', 'Thursday', 'Friday']
list.pop([index=-1])通过index移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
y = x.pop()
print(y) # Friday
y = x.pop(0)
print(y) # Monday
y = x.pop(-2)
print(y) # Wednesday
print(x) # ['Tuesday', 'Thursday']
del list[index1:index2]移除列表内指定范围(index1<= index
删除元素并不再使用,使用del,删除元素的同时使用元素,使用pop()命令。
x = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
del x[0:2]
print(x) # ['Wednesday', 'Thursday', 'Friday']
单个元素获取
通过元素的索引值进行索引。对于列表x,获得元素为x[0],x[1],…,x[-2],x[-1]。
从列表中截取子列表(切片)
切片结构 x[start(=0) : stop(=-1) : step(=1)](括号内代表默认)
。
x[start:]
从start索引开始到列表末尾,步长step默认为1。x[:stop]
从列表开头到stop索引之前一个元素,步长step默认为1。x[start:stop]
从start索引至stop索引之前切片,步长step默认为1。x[start:stop:step]
从start至stop之前按照间隔采样切片,注意当step为-1时为列表反向排列。x[:]
为x的浅拷贝。补充知识:浅拷贝、深拷贝和赋值的浅显理解
下表对于具有多层的数据而言,如列表等。第一层为一级元素。
与原数据指向同一地址 | 第一层数据为基本数据类型 | 原数据包含子对象 | |
---|---|---|---|
赋值 | 是 | 改变使源数据改变 | 改变使原数据改变 |
浅拷贝 | 否 | 改变不会使源数据改变 | 改变使源数据改变 |
深拷贝 | 否 | 改变不会使源数据改变 | 改变不会使源数据改变 |
赋值:传递对象的引用而已,原始列表list1改变,被赋值的list2也会做相同的改变,反之亦然。
list1 = [i for i in range(10)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list2 = list1
list2[0] = 1
print(list2)
print(list1)
# [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [1, 1, 2, 3, 4, 5, 6, 7, 8, 9]
浅拷贝:拷贝父对象,不会拷贝对象的内部的子对象。即拷贝列表name里面的一级元素的内存地址,不拷贝list1里的小列表里的元素的内存地址。所以改变原数据list1的子对象会导致list2也改变,改变一级元素不会改变list2。
改变list1一级元素list2不发生改变
list1 = [i for i in range(10)]
list1.append(['micheal','mary'])
print(list1)
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['micheal', 'mary']]
list2 = list1[:]
# list1[10][0] = 'MICHEAL'
list1[10] = ['JayChou']
print(list1)
print(list2)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['JayChou']]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['micheal', 'mary']]
改变list1中子对象list2发生改变。
list1 = [i for i in range(10)]
list1.append(['micheal','mary'])
print(list1)
list2 = list1[:]
list1[10][0] = 'MICHEAL'
# list1[10] = ['JayChou']
print(list1)
print(list2)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['micheal', 'mary']]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['MICHEAL', 'mary']]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ['MICHEAL', 'mary']]
==
,只有成员和成员的顺序相同才返回True+
,需要创建新的list对象,消耗较大内存,尽量使用添加元素三个函数实现。*
in
、not in
函数 | 解释 |
---|---|
list.count(obj) |
统计object在列表中出现次数 |
list.index(x[, start[, end]]) |
从列表切片中中找出某个值第一个匹配项的索引位置 |
list.reverse() |
反向列表中元素 |
list.sort(key=None, reverse=False) |
对原列表进行排序。key为用来比较的对象(对于多维而言,如二维数组,取每一维的第二个元素比较),reverse为排序规则,True降序False升序(默认) |
# 获取列表的第二个元素
def takeSecond(elem):
return elem[1]
x = [(2, 2), (3, 4), (4, 1), (1, 3)]
x.sort(key=takeSecond)
print(x)
# [(4, 1), (2, 2), (1, 3), (3, 4)]
1.列表操作练习
列表lst 内容如下
lst = [2, 5, 6, 7, 8, 9, 2, 9, 9]
请写程序完成下列操作:
lst = [2, 5, 6, 7, 8, 9, 2, 9, 9]
print(lst)
lst.append(15)
print(lst)
lst.insert(5,20)
print(lst)
lst.extend([2, 5, 6])
print(lst)
lst.pop(3)
print(lst)
lst.reverse()
print(lst)
lst.sort(reverse=False)
print(lst)
lst.sort(reverse=True)
print(lst)
# [2, 5, 6, 7, 8, 9, 2, 9, 9]
# [2, 5, 6, 7, 8, 9, 2, 9, 9, 15]
# [2, 5, 6, 7, 8, 20, 9, 2, 9, 9, 15]
# [2, 5, 6, 7, 8, 20, 9, 2, 9, 9, 15, 2, 5, 6]
# [2, 5, 6, 8, 20, 9, 2, 9, 9, 15, 2, 5, 6]
# [6, 5, 2, 15, 9, 9, 2, 9, 20, 8, 6, 5, 2]
# [2, 2, 2, 5, 5, 6, 6, 8, 9, 9, 9, 15, 20]
# [20, 15, 9, 9, 9, 8, 6, 6, 5, 5, 2, 2, 2]
2.修改列表
问题描述:
lst = [1, [4, 6], True]
请将列表里所有数字修改成原来的两倍。
lst = [1, [4, 6], True]
for index, elem in enumerate(lst):
if isinstance(elem, list):
for index1, elem1 in enumerate(elem):
lst[index][index1] = elem1 * 2
elif isinstance(elem, bool):
pass
else:
lst[index] = elem * 2
print(lst)
# [2, [8, 12], True]
3.山脉数组的峰顶索引
我们把符合下列属性的数组 A 称作山脉:
A.length >= 3
存在 0 < i < A.length - 1 使得A[0] < A[1] < … A[i-1] < A[i] > A[i+1] > … > A[A.length - 1]
给定一个确定为山脉的数组,返回任何满足 A[0] < A[1] < … A[i-1] < A[i] > A[i+1] > … > A[A.length - 1] 的 i 的值。
示例 1:
输入:[0,1,0]
输出:1
示例 2:
输入:[0,2,1,0]
输出:1
提示:
3 <= A.length <= 10000
0 <= A[i] <= 10^6
A 是如上定义的山脉
利用列表的方法
class Solution:
def peakIndexInMountainArray(self, A: List[int]) -> int:
length = len(A)
for i in range(1,length):
b = A[:i]
b.sort()
if b == A[:i]:
print(i)
break
最简单方法(找到最大值)
class Solution:
def peakIndexInMountainArray(self, A: List[int]) -> int:
return A.index(max(A))