python数据容器之列表

1.列表部分

1.1列表的定义

# 列表:是一个数据容器,是用来容纳若干数据的
#      是一个有序的、可变的数据容器
#      有序: 元素的添加顺序和存储顺序是一致的,可以使用下标(索引)访问元素
#      可变: 列表中的元素可以做到随时的添加、删除、修改
# 注意事项:
#      理论上来说,列表中可以存储不同数据类型的元素
#      但是,在实际开发中,我们需要保证数据的类型一致

# 1. 字面量: 需要将元素写入到一对[]中
l1 = [1, 2, 3, 4, 5]
print(l1)

l2 = []
print(l2)

# 2. 通过 list() 函数,将其他的容器,转成列表
l3 = list("hello world")
print(l3)

l4 = list((1, 2, 3, 4, 5))
print(l4)

l5 = list(range(0, 20, 2))
print(l5)

1.2 列表的运算符

运算符描述示例
+将两个列表拼接[1, 2, 3, 4, 5] + [9, 8, 7, 6, 5]
*将列表中的元素重复若干次[1, 2, 3] * 3
+=在现有值的基础上拼接s1 = [1, 2, 3, 4, 5] ,s1+= [9, 8, 7, 6, 5]
*=在现有值的基础上重复s1 = [1, 2, 3] s1 *= 3
==判断两个列表是否相同[1, 2, 3] == [1, 2, 3]
!=判断两个列表是否不同[1, 2, 3] != [1, 2, 3]
>判断列表的大小关系[1, 2, 3] > [1, 1, 2]
<判断列表的大小关系[1, 2, 3] < [1, 1, 2, 2]
>=判断列表的大小关系[1, 2, 3] >= [1, 2, 3]
<=判断列表的大小关系[1, 2, 3] <= [1, 2, 3]
in判断一个数据是否在一个列表中包含3 in [1, 2, 3]
not in判断一个数据是否不在一个列表中包含3 not in [1, 2, 3]
# + : 将两个列表拼接到一起,生成一个新的列表
# * : 将一个列表中的元素,重复若干次,生成一个新的列表
# += : 将两个列表拼接到一起,生成一个新的列表,并且给自己重新赋值
# *= : 将一个列表中的元素,重复若干次,生成一个新的列表,并且给自己重新赋值
# > < >= <= == != : 进行两个列表中的元素比较的
# in : 判断一个数据,是否在一个列表中包含
# not in :

print([1, 2, 3, 4, 5] + [9, 8, 7, 6, 5])
print([1, 2, 3] * 3)

list1 = [1, 2, 3, 4, 5]
list1 += [9, 8, 7, 6, 5]
print(list1)

list2 = [1, 2, 3]
list2 *= 3
print(list2)

print([1, 2, 3, 4, 5] > [1, 1, 2, 2, 3])

print(4 in [1, 2, 3, 4, 5])

1.3 列表的索引和切片

列表中的元素是有序的,每一个元素也可以使用索引来确定位置。那么我们就可以使用索引来操作指定位的元素,使用切片来获取指定范围的元素。
索引和切片的使用,与字符串的基本一致。

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

# 索引的使用
print(list1[4])
print(list1[-6])

# 切片的使用
print(list1[2:7])
print(list1[6:1:-1])

但是列表和字符串还是不同的,列表是可变的,也就是说,可以通过索引来修改指定位置的元素

# 列表是可变的,可以通过索引,修改列表中的元素的
list1[4] = 50
print(list1)

# 也可以通过切片,修改指定范围的元素
# 在替换的时候,长度可以不相同
list1[2:6] = [0, 0, 0, 0, 0, 0]
print(list1)

1.4列表的遍历

# 遍历方式与字符串完全相同
list1 = [1, 2, 3, 4, 5, 6, 7]

# 直接遍历列表中的每一个元素
for i in list1:
    print(i)

print("-*" * 30)

# 通过下标遍历
for i in range(len(list1)):
    print(f"list1[{i}] = {list1[i]}")

print("-*" * 30)

for i, e in enumerate(list1):
    print(f"list1[{i}] = {e}")

1.5 列表的元素操作

函数描述示例
append(__object)添加一个元素到列表的末尾list1 = [1, 2, 3, 4]list1.append(5)
insert(__index, __object)将一个元素添加到列表的指定下标位置list1 = [1, 2, 3, 4, 5]
list1.insert(0, 100)
extend(__iterable)添加一个容器中的元素,到当前列表的末尾,相当于 +=list1 = [1, 2, 3, 4, 5],list2.extend([10, 20, 30])
pop(__index)删除指定下标位的元素,默认是最后一位__index: 需要删除的元素的下标,默认是最后一位返回值: 刚刚被删除的元素list1 = [1, 2, 3, 4, 5]list1.pop()list1.pop(2)
remove(__value)删除列表中的指定元素。注意事项:如果这个元素不存在,报错如果存在多个,只删除第一个list1 = [100, 200, 300, 100],list1.remove(100)
clear()清空列表中的所有元素list1 = [1, 2, 3, 4, 5],list1.clear()
index(__value, __start, __stop)在指定范围内查找指定元素的下标如果找不到,会报错__value: 需要查找的元素__start: 开始查找的下标,默认开始__stop: 结束查找的下标,默认结尾list1 = [1, 2, 3, 4, 5],list1.index(2),list1.index(2, 1, 5)
count(__value)查找列表中某一个元素出现了多少次list1 = [1, 1, 2, 3, 4],list1.count(1)
# 创建一个列表
list1 = []

# 增
list1.append(123)
list1.append(456)
list1.append(789)

# 增: 将一个容器中的所有元素,添加到末尾
list1.extend([1, 2, 3])
list1.extend((0, 1, 0, 1, 0))

# 增:
list1.insert(3, 100)
# 注意事项: 越界的情况,不会报错
#         如果是正向索引(正数),插入到列表的最后
#         如果是负向索引(负数),插入到列表的最前
list1.insert(-100, 999)
print(list1)


# 删除: 按照索引(下标)位去删除
# pop(_index): 删除指定下标位的元素
#              _index: 需要删除的下标,默认是最后一位
#              返回值: 被删除的元素
print(list1.pop(3))

# 删除: 按照元素删除
# remove(_value): 按照元素去删除的
#                 1. 如果删除的元素不存在,他会报错 ValueError
#                 2. 如果元素存在多个,只会删除最开始的一个
list1.remove(0)

# 删除: 清空所有
# list1.clear()

print(list1)


# 查找元素下标
# 如果元素不存在,会报错
print(list1.index(1))

# 查找元素在列表中出现的次数
print(list1.count(1))




# # 需求: 删除所有的0
# while 0 in list1:
#     list1.remove(0)
#
# print(list1)


# list2 = []
# for i in range(0, 101, 2):
#     list2.append(i)
#
# print(list2)

# list2 = []
# list2.extend(range(0, 101, 2))
# print(list2)


# 需求: 查询一个列表中,某一个元素最后一次出现的下标
def last_index(l: list, e: int) -> int | None:
    # 思路:
    # 从后往前遍历每一个元素,和需要查找的元素进行比较
    # 如果找到相同的元素了,直接返回下标
    for i in range(len(l) - 1, -1, -1):
        if l[i] == e:
            return i

    return None


list3 = [1, 2, 3, 4, 5, 5, 6, 6, 4, 3, 2, 1]
print(last_index(list3, 30))

1.6 列表的其他操作

函数描述示例
max(_iterable)获取一个容器中的最大值max([1, 2, 3, 4, 5])
min(_iterable)获取一个容器中的最小值min([1, 2, 3, 4, 5])
sort(key, reverse)将一个列表中的元素进行从小到大的升序排序。key: 函数类型,自定义排序的依据reverse: bool类型,在排序完成之后,执行翻转操作,达到降序排列的效果list1 = [“hello”, “hi”, “Tom”],list1.sort(),list1.sort(reverse=True),list1.sort(key=abs),list1.sort(key=abs, reverse=True)
reverse()将一个列表中的元素翻转list1 = [1, 2, 3, 4, 5],list1.reverse()
copy()生成一个列表的深拷贝list1 = [1, 2, 3, 4, 5],list2 = list1.copy()

reverse 和切片的区别:

reverse和切片都可以获取到一个翻转之后的列表,但是区别在于:
切片,是获取到一个新的列表,原来列表中的元素是不会改变的
reverse,是将列表中的元素直接翻转的

# max、min: 这个函数,并不是list独有的函数,是系统内置的函数
# max: 从一个容器中,获取到最大值
print(max([1, 2, 3, 3, 4, 4, 4, 3, 4, 2, 7, 6, 5, 4, 7, 6, 3]))

# min: 从一个容器中,获取到最小值
print(min([1, 2, 3, 3, 4, 4, 4, 3, 4, 2, 7, 6, 5, 4, 7, 6, 3]))


# 排序: sort 可以将一个列表中的元素,按照一定的大小关系,重新排列
# sort(): 默认是升序排序
#       reverse: 排序之后,反转
l1 = [1, 2, 3, 3, 2, 1, 1, 2, 5, 6, 7, 8, 9, 8, 7, 6, 5, 3, 0, 1, 2]
l1.sort()
print(l1)

l1.sort(reverse=True)
print(l1)

# 翻转:
l2 = [1, 2, 3, 4, 5]
l2.reverse()
print(l2)

# reverse和切片的区别:
# 切片: 会得到一个新的列表的,原来的列表中的内容是没有变化的
# reverse: 直接修改的原来的列表
l3 = [1, 2, 3, 4, 5]
# print(l3[::-1])
# print(l3)
# l3.reverse()
# print(l3)

1.7 列表的内存分析

无论是创建了一个什么容器(字符串、列表、元组、集合、字典),都需要在堆空间中进行内存的分配,用来存储若干的元素。而容器类型的变量,只是存储的这个堆空间的内存地址。

# 创建一个列表容器
# 此时需要在堆空间开辟空间,存储 1, 2, 3, 4, 5 五个元素
# list1 只是存储的这个堆空间的内存地址
list1 = [1, 2, 3, 4, 5]

1.7.1浅拷贝

直接将一个变量中存储的内存地址,赋值给另外的一个变量,这个过程叫做“浅拷贝”。
浅拷贝不会有新的堆空间开辟,得到的两个容器类型的变量,其实存储的都是地址,指向的是相同的空间。因此修改一个容器中的数据,对另外一个都会造成影响。

# 创建一个列表容器
# 此时需要在堆空间开辟空间,存储 1, 2, 3, 4, 5 五个元素
# list1 只是存储的这个堆空间的内存地址
list1 = [1, 2, 3, 4, 5]

# 直接将 list1 中存储的内存地址,赋值给了list2
# 这就是一个浅拷贝,list2 中存储的依然是指向前面开辟的堆空间
list2 = list1

# 通过list2来修改元素
list2[2] = 30

# 然后发现list1也随之修改了,原因就是浅拷贝的问题
print(list1)

1.7.2深拷贝

在堆空间中开辟一个新的空间,将原来容器中的每一个元素拷贝到这个新的空间中。这个过程叫“深拷贝”。深拷贝会产生新的堆空间,得到的容器类型的变量,也是指向新的堆空间的地址,因此对原来的容器没有影响。

# 创建一个列表容器
# 此时需要在堆空间开辟空间,存储 1, 2, 3, 4, 5 五个元素
# list1 只是存储的这个堆空间的内存地址
list1 = [1, 2, 3, 4, 5]

# 创建一个新的空间
list2 = []
# 将list1中的元素拷贝到新的空间中
list2.extend(list1)

# 修改list2
list2[2] = 30

# list1没有修改
print(list1)
# 堆
# 现在需要开辟出空间,来存储这5个数字,是在堆上开辟的空间
# 此时的l1存储的是这块空间的内存地址
l1 = [1, 2, 3, 4, 5]

# 赋值操作,将l1的值赋值给l2
# l1中存储的是一个地址,因此这时将这个地址给了l2
# 也就是说,现在的l2也指向了堆上的那一块空间
l2 = l1

# 修改列表中的元素
# 通过l2中存储的地址,找到堆空间
# 找到堆空间之后,再通过索引,找到具体的元素的空间
# 将其修改成了30
l2[2] = 30

print(f"{l1 = }, {l2 = }")


# 在上方,将一个容器的内存地址,直接给到另外一个变量进行赋值
# 这样的操作,称为 -- 浅拷贝
# 浅拷贝,其实,只是生成了一个新的变量,用来存储地址。

# 深拷贝:
# 创建一个新的容器,将原来的容器中的元素,添加到新的容器中
# 生成的就是一个新的容器
l3 = []
l3.extend(l1)

l3[2] = 300
print(f"{l1 = }, {l3 = }")

l4 = l1.copy()

1.8 列表的高级排序

在排序的时候,调用 sort 函数,可以通过参数 key,传递一个排序的依据	
			实现按照指定的规则进行排序。
排序逻辑: 将每一个元素带入到 key 的函数中,用返回值作为排序的依据。
		在排列元素的时候,将按照这个返回值进行排序。

eg:

l1 = ["hello", "hi", "Lily", "SanPang", "Tom", "LiHua"]

# 需求: 希望对l1进行排序,排序的依据: 按照字符串的长度
# key: 需要指定一个排序的依据,需要的是一个函数
#      逻辑: 将每一个元素带入到这个函数中,使用返回值作为排序的依据
# 定义一个函数,获取字符串的长度
l1.sort(key=len)
print(l1)


l2 = [10, 12, -11, 9, 12, -13, 10, -20]
# 需求: 希望对l2进行排序,排序的依据: 按照绝对值排序
l2.sort(key=abs)
print(l2)


def get_reverse_string(s):
    return s[::-1]

l3 = ["hello", "abc", "world", "lalala"]
# 需求: 希望对l3进行排序,排序的依据: 按照最后一个字母进行排序,如果相同,比较前面的一位字母
# l3.sort(key=lambda x: x[::-1])
l3.sort(key=get_reverse_string)
print(l3)

1.9 系统内置的高阶函数

高阶函数:如果一个函数的参数或者返回值,是另外一个函数。那么这样的函数就是高阶函数。

函数说明示例
max(_iterable, key)按照指定的规则,获取到一个列表中的最大值。 key: 指定的规则,将每一个元素带入到这个函数中,用返回值作为大小比较的依据。list1 = [1, -2, 3, -4]
max(list1, key=abs),min(_iterable, key)按照指定的规则,获取到一个列表中的最小值。key: 指定的规则,将每一个元素带入到这个函数中,用返回值作为大小比较的依据。list1 = [1, -2, 3, -4]
min(list1, key=abs),sorted(_iterable, key, reverse)将一个容器中的元素进行生序排序,并返回升序排序之后的新的容器。key: 排序的依据reverse: 排序之后是否需要翻转list1 = [1, 2, -3, -4, 5]
sorted(list1),sorted(list1, key=abs),filter(function, _iterable)过滤,保留下来满足条件的数据,过滤掉不满足条件的数据function: 是一个判断函数,参数是每一个元素,返回值是bool类型_iterable: 需要过滤的容器是谁l2 = [89, 79, 88, 59, 58, 90, 66, 65, 55, 100]
res2 = list(filter(lambda x: x < 60, l2))map(function, _iterable)映射,将容器中的每一个元素,替换成其他的元素function: 提供一个映射函数,接收容器中的每一个元素,返回替代值l3 = [“xiaoming”, “lily”, “lucy”, “uncle wang”],res4 = list(map(lambda x: x.upper(), l3))

eg:

# sorted: 对一个列表进行排序,但是不会对列表本身产生影响,而是返回一个排序之后的新的列表
#     如果不想改变列表中的元素的顺序,就使用sorted
#     如果想要改变列表中的元素的顺序,就使用liebiao.sort

l1 = [1, 3, 5, 7, 9, -2, -4, -6, -8, -10]
res1 = sorted(l1, key=abs, reverse=True)
print(res1)

# max、min
# key: 设置一个比较的依据,逻辑是将每一个元素,带入到key的函数中来,使用返回值进行比较
# 需求: 找到一个列表中的绝对值最大的数字
print(max(l1, key=abs))
# 需求: 找到一个列表中的绝对值最小的数字
print(min(l1, key=abs))

# filter: 过滤,保留下来满足条件的数据,过滤掉不满足条件的数据
#         第一个参数: 是一个判断函数,参数是每一个元素,返回值是bool类型
#         第二个参数: 需要过滤的容器是谁
#         返回值: 是一个 filter object,如果需要转成列表的话,只需要使用 list()
l2 = [89, 79, 88, 59, 58, 90, 66, 65, 55, 100]
# 需求: 需要找到所有的不及格的成绩
res2 = list(filter(lambda x: x < 60, l2))
print(res2)

# 需求: 找到一个字符串中所以的数字
s1 = "hello123world456abc789"
res3 = list(filter(lambda x: x.isdigit(), s1))
print("".join(res3))


# map: 映射,将容器中的每一个元素,替换成其他的元素
#      提供一个映射函数,接收容器中的每一个元素,返回替代值
l3 = ["xiaoming", "lily", "lucy", "uncle wang"]
# 需求: 需要将每一个字符串,都换成大写
res4 = list(map(lambda x: x.upper(), l3))
print(res4)

1.10列表推导式

目的: 为了创建一个新的列表,在新的列表创建的时候,可以根据一个已有的序列,对其中的元素进行映射、过滤
映射: [映射的操作 for 迭代队列 in 序列]
过滤: [映射的操作 for 迭代队列 in 序列 if 过滤条件]

# 列表推导式
#    目的: 为了创建一个新的列表,在新的列表创建的时候,可以根据一个已有的序列,对其中的元素进行映射、过滤
#    映射: [映射的操作 for 迭代队列 in 序列]
#    过滤: [映射的操作 for 迭代队列 in 序列 if 过滤条件]

# 需求: 构建一个新的列表,新的列表中的元素,是l1中的每一个元素的值 x2
l1 = [10, 20, 30, 40, 50]

# 使用列表推导式
l2 = [i * 2 for i in l1]
print(l2)


# 需求: 有一个列表,存储的都是数字
#      需要将他们拼接成一个字符串,使用-分隔
#      "10-20-30-40-50-60"
numbers = [10, 20, 30, 40, 50, 60]
numbers2 = [str(n) for n in numbers]
print("-".join(numbers2))

# 需求: 有一个纯数字的列表,其中存储的是成绩
#      将所有的不及格的成绩提取到一个新的列表中
scores = [78, 55, 67, 45, 98, 50, 66]
scores2 = [s for s in scores if s < 60]
print(f"{scores2 = }")

# 需求: 将所有的及格成绩,拼接成一个字符串,使用逗号分隔
print(",".join([str(s) for s in scores if s >= 60]))


# 需求: There is no denying that successful business lies in a healthy body and mind
# 提取这句话中包含 i 的单词
line = "There is no denying that successful business lies in a healthy body and mind"
words = line.split()
res = [x for x in words if 'i' in x]
print(res)

# #
# res1 = []
# for i in l1:
#     res1.append(i * 2)
# print(f"{res1 = }")
#
# #
# res2 = list(map(lambda x: x * 2, l1))
# print(f"{res2 = }")
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值