list列表
可变数据类型:值改变,id不变,证明改的是原值,证明原值是可以被改变的
==不可变类型:==值改变,id也变了,证明是产生新的值,压根没有改变原值,证明原值是不可以被修改的
x = 1
print(id(x))
x = 2
print(id(x))
# 产生了新的内存地址,所以 int 是不可变数据类型
1578751650096
1578751650128
l = [1, 2, 3]
print(id(l))
l[0] = 11
print(l)
print(id(l))
# 值改变,但是内存地址不变,所以 list 是可变数据类型
2437631521536
[11, 2, 3]
2437631521536
列表、字典是可变的数据类型
fruit = ['apple', 'true', 'peal', 'watermelon']
for i in fruit:
print(i)
结果:
apple
true
peal
watermelon
list的CRUD
方法 | 要点 | 描述 |
---|---|---|
list.append(x) | 增加元素 | 将元素x增加到列表list尾部 |
list.extend(aList) | 增加元素 | 将列表alist所有元素加到列表list尾部 |
list.insert(index,x) | 增加元素 | 在列表list指定位置index处插入元素x |
list.remove(x) | 删除元素 | 在列表list中删除首次出现的指定元素x |
list.pop([index]) | 删除元素 | 删除并返回列表list指定为止index处的元素,默认是最后一个元素 |
list.clear() | 删除所有元素 | 删除列表所有元素,并不是删除列表对象 |
list.index(x) | 访问元素 | 返回第一个x的索引位置,若不存在x元素抛出异常 |
list.count(x) | 计数 | 返回指定元素x在列表list中出现的次数 |
len(list) | 列表长度 | 返回列表中包含元素的个数 |
list.reverse() | 翻转列表 | 所有元素原地翻转 |
list.sort() | 排序 | 所有元素原地排序 |
list.copy() | 浅拷贝 | 返回列表对象的浅拷贝 |
增
fruit_list = ['apple', 'true', 'peal', 'watermelon']
fruit_list.append('fruit')
print(fruit_list)
改
fruit_list = ['apple', 'true', 'peal', 'watermelon']
fruit_list[0]='APPLE'
print(fruit_list)
结果:
['APPLE', 'true', 'peal', 'watermelon']
删
remove 删除 value
fruit_list = ['apple', 'true', 'peal', 'watermelon']
fruit_list.remove('peal')
print(fruit_list)
结果:
['apple', 'true', 'watermelon']
del
输出指定的元素
l1 = [11, 22, 33, 44, 55]
del l1[1]
print(l1)
# 或者使用 pop
l1 = [11, 22, 33, 44, 55]
l1.pop(0)
print(l1)
查
通过使用下标的方式:
fruit_list = ['apple', 'true', 'peal', 'watermelon']
print(fruit_list[0])
查列表的元素数量: 使用 len
函数
反转列表
list倒序,也称为反转
fruit_list = ['apple', 'true', 'peal', 'watermelon']
print(fruit_list[::-1])
结果:
['watermelon', 'peal', 'true', 'apple']
合并多个列表
fruit_list = ['apple', 'true', 'peal', 'watermelon']
tools = ['cut', 'qie']
fruit_list.extend(tools)
print(fruit_list)
['apple', 'true', 'peal', 'watermelon', 'cut', 'qie']
下标
列表的下标也叫索引。其中反向索引以-1开始。如图:
1.已知一个元素,求它的下标
name = ['A', 'B', 'C', 'D']
print(name.index('D'))
3
shop_list = [
['包子', 2],
['馒头', 1],
['面条', 10]
]
for index, item in enumerate(shop_list):
shop_name, shop_price = item
print(f'商品编号为:{index}, 商品名称为:{shop_name}, 商品价格为:{shop_price}')
enumerate()
遍历shop_list
中的每个元素,并返回一个(index, item)
对,其中index
是当前元素的索引,item
是该索引对应的元素
enumerate(shop_list)
会生成:
(0, ['包子', 1])
(1, ['馒头', 1])
(2, ['面条', 1])
赋值解包:
shop_name, shop_price = item
,使用解包将每个子列表的两个元素分别赋值给shop_name
和shop_price
列表切片等于浅拷贝
-
l1[1:2]
表示从索引1
(包含)到索引2
(不包含)提取元素 -
l1 = l1[1:2]
将提取的切片[22]
重新赋值给l1
,原来的列表被覆盖
l1 = [11, 22, 33, 44, 55]
print(id(l1))
l1= l1[1:2]
print(l1)
print(id(l1))
# 结果
2332823593664
[22]
2332826662784
队列,先进先出
l = []
# 入队操作
l.append(11)
l.append(22)
l.append(33)
l.append(44)
# 出队操作
l.pop()
print(l)
l.pop()
print(l)
l.pop()
print(l)
# 运行结果
[11, 22, 33]
[11, 22]
[11]
双列表
深浅拷贝
浅拷贝案例
- 把原列表第一层的内存地址不加区分完全copy一份给新列表
list1 = [1, 2, 3]
list2 = list1.copy()
print(id(list1), id(list2))
# 结果为:
2305058222848 2305061287360
import copy
list1 = [1, 2, [3, 4]]
list2 = copy.copy(list1) # 浅拷贝
list2[2][0] = 99 # 修改嵌套对象
print("list1:", list1, 'id:', id(list1))
print("list2:", list2, 'id:', id(list2))
'''
list1: [1, 2, [99, 4]] id: 2137356798016
list2: [1, 2, [99, 4]] id: 2137356800256
'''
list1
和list2
是两个独立的列表对象- 嵌套的子列表
[3, 4]
是共享的,因此修改子列表的内容会同时影响list1
和list2
深拷贝:针对可变类型产生了新的一份内存地址。会递归地拷贝对象及其内部的嵌套对象,确保新对象与原始对象在内存上完全独立
import copy
list1 = [1, 2, [3, 4]]
list3 = copy.deepcopy(list1) # 深拷贝
list3[2][0] = 9 # 修改嵌套对象
print("list1:", list1, 'id:', id(list1))
print("list3:", list3, 'id:', id(list3))
'''
list1: [1, 2, [3, 4]] id: 140657294436616
list3: [1, 2, [9, 4]] id: 140657294437896
'''
list1
和list3
是完全独立的,嵌套对象[3, 4]
也被复制为一个新的对象- 修改
list3
的嵌套对象不会影响list1
1求Bob的薪资
names = ['Alice', 'Bob', 'Charlie', 'David']
salaries = [5000, 6000, 5500, 7000]
# 求Bob的下标
index_Bob = names.index('Bob')
# 把求出的下标代入列表 salaries
print(salaries[index_Bob])
2.求每一个员工的薪资
names = ['Alice', 'Bob', 'Charlie', 'David']
salaries = [5000, 6000, 5500, 7000]
# 打印每个员工的姓名和薪水
for i in range(len(names)):
print(f'{names[i]} salary = {salaries[i]}')
result:
Alice salary = 5000
Bob salary = 6000
Charlie salary = 5500
David salary = 7000
3.求最高薪资者的姓名
names = ['Alice', 'Bob', 'Charlie', 'David']
salaries = [5000, 6000, 5500, 7000]
print(names[salaries.index(max(salaries))])
print(names[salaries.index(min(salaries))])
列表结合循环和判断
1.判断质数的有哪些:
# 第一个列表用于定义要判定的数字范围
list0 = []
for i in range(1, 101):
list0.append(i)
for num in range(1, 101):
for i in range(2,num):
if num % i == 0:
list0.remove(num)
break
print(list0)
2.根据输入,把范围内的质数和非质数写入列表当中
# 获取用户输入的数字范围
start = int(input("请输入起点: "))
end = int(input("请输入终点: "))
# 初始化质数和非质数列表
primes = []
non_primes = []
# 遍历范围
for num in range(start, end + 1):
if num < 2:
non_primes.append(num) # 小于2的数不是质数,直接累计到列表
else:
is_prime = True # 初始定义 is_prime 为True
for i in range(2, num): # 检查是否可以被其他数整除
if num % i == 0: # 如果每一次被除都是0,说明是非质数
is_prime = False # 所以把 is_prime 设置为False
break # 跳出内层for循环
if is_prime: # 处理 is_prime 结果
primes.append(num) # 根据判断结果去增加对应的列表元素
else:
non_primes.append(num)
# 打印结果
print("质数列表:", primes)
print("非质数列表:", non_primes)
当num=2时,就会判断
is_prime = True
for i in range(2, 2): # 循环的范围为空,因此不会进入循环体
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(num) # 所以直接判定2为质数
else:
non_primes.append(num)
3.一个袋子里有3个红球,3个绿球,6个黄球,一次从袋子里取6个球,列出所有可能组合
- 可以使用一个列表存储所有的组合
- 红球用
range(0, 4)
表示,绿球同理,黄球用数字6减去红球数量和绿球数量 - 最后把3种球的数量加入列表中
# 初始化结果列表
combinations = []
for r in range(4):
for g in range(4):
# 计算黄球抓取数量 y
y = 6 - r - g
combinations.append((r, g, y))
for comb in combinations:
print(comb)
count = len(combinations)
print('{}种组合'.format(count))
tuple元组
元组的基本使用
元组就相当于是只读的列表,因为只读,所以没有append、remove修改等操作方法.
t = (1, 2, [3, 4])
print(id(t))
t[2][0] = 3333
print(t)
print(id(t))
# 输出
2288681794176
(1, 2, [3333, 4])
2288681794176
它只有两个操作方法:count,index
元组、字符串列表都属于序列。所以元组也可以切片
tuple = (1, 2, 3, 4)
print(type(tuple))
<class 'tuple'>
2.遍历输出每一个元素
tuple = (1, 2, 3, 4, 5)
for i in tuple:
print(i)
1
2
3
4
5
3.元组的切片,倒序取出,然后再倒序排序
name1 = ('a', 'b', 'c', 'd', 'e')
name2 = tuple(name1)
print(name2[-1:-3:-1])
('e', 'd')
列表和元组的结合
emp2 = (['A', 18000], ['B', 13000], ['C', 12000], ['D', 78000])
print(emp2)
元组数据部不可变,但是有列表则可以
emp2 = (['A', 18000], ['B', 13000], ['C', 12000], ['D', 78000])
emp2[0][1] = 19000
print(emp2)(['A', 19000], ['B', 13000], ['C', 12000], ['D', 78000])
运行结果为:
(['A', 19000], ['B', 13000], ['C', 12000], ['D', 78000])
查看内存地址没有变化
emp2 = (['A', 18000], ['B', 13000], ['C', 12000], ['D', 78000])
print(id(emp2))
emp2[0][1] = 19000
print(id(emp2))
2083274028832
2083274028832
dict字典
字典基础语法
集合和字典一样都是使用大括号。但集合没有value,相当于只有字典的key。字符串、列表和元组属于序列,是有序的,但集合是无序的,所以不能通过下标来查询和修改元素。
字典的value可以是任意对象,包括列表、字典、函数
再总结一下:
整数,字符串,元组是不可变数据类型(整数和字符串改变值的话是在内存里开辟新的空间来存放新值,原内存地址里的值不变)
列表转字典
l_info = [
['name', 'wzy'],
['age', 18],
['sex', 'man']
]
d = {}
for item in l_info:
# l_info 子列表的第一个元素作为 key , 第二个元素作为 value
d[item[0]]=item[1]
print(d)
更简单的方法:
l_info = [
['name', 'wzy'],
['age', 18],
['sex', 'man']
]
d = dict(l_info)
print(d)
创建字典方式2:
d = {}.fromkeys('name', 'wzy')
print(d)
{'n': 'wzy', 'a': 'wzy', 'm': 'wzy', 'e': 'wzy'}
查:
dict1 = {
'id1': 'wzy',
'id2': 'a',
'id2': 'b'
}
print(dict1['id1'])
print(dict1["stu01"]) # 如果key值不存在,会返回keyerror错误
print(dict1.get("stu01")) # 这种取值方法如果key值不存在,会返回none,不会返回错误
# 查多个,只需要写读个index
print(dict1['index1']['zi_index2'])
增:
dict1 = {
'id1': 'wzy',
'id2': 'a',
'id2': 'b'
}
dict1['id3'] = 'c'
print(dict1)
打印key 和 value
dict1 = {
'name': 'wzy',
'age': '18',
'sex': 'man'
}
for key, value in dict1.items():
print(key, value)
# 运行结果:
name wzy
age 18
sex man
遍历方式1:
dict1 = {
'id0': 'wzy',
'id1': 'a',
'id2': 'b'
}
for i in dict1:
print(i)
for i in dict1.values():
print(i)
遍历方式2:
func_dic = {
'k1': 'v1',
'k2': 'v2',
'k3': 'v3'
}
for k in func_dic:
print(k, func_dic[k])
# 运行结果为:
k1 v1
k2 v2
k3 v3
删除一个value
d = {
'k1': 'k11',
'k2': 'k22'
}
d.pop('k1')
print(d)
# 输出
{'k2': 'k22'}
修改字典
- 老字典中不存在的key,就会直接写入到字典中
d = {
'k1': 'k11'
}
d.update({'k2': 'k222', 'k3': 'k333'})
print(d)
输出
{'k1': 'k11', 'k2': 'k222', 'k3': 'k333'}
给字典设置默认值
# d = {'name': 'wzy'}
d = {}
d.setdefault('name', 'wzy666')
print(d)
字典嵌套
改多个:
字典是可变类型,修改后需要打印验证
class_all = {
'class01': {
'name1': 'a',
'name2': 'b',
'name3': 'c'
},
'class2': {
'cat1': 'black',
'dog': 'white',
'cow': 'blue',
},
'class3': {
'hobby1': 'blog',
'hobby2': 'golf',
'hobby3': 'game'
}
}
class_all['class01']['name1'] = 'wzy666'
print(class_all)
在嵌套中查
class_all = {
'class1': {
'name1': 'a',
'name2': 'b',
'name3': 'c'
},
'class2': {
'cat1': 'black',
'dog': 'white',
'cow': 'blue',
},
'class3': {
'hobby1': 'blog',
'hobby2': 'golf',
'hobby3': 'game'
}
}
for index, i in enumerate(class_all['class1']['name1']):
print(index, i)
for index, i in enumerate(class_all['class1']['name2']):
print(index, i)
for index, i in enumerate(class_all['class1']['name3']):
print(index, i)
for key, value in class_all['class1'].items():
print(key, value)
运行结果:
0 a
0 b
0 c
name1 a
name2 b
name3 c
-
第一条print打印了 class1 的键以及键的索引
字典案例
def login():
print('登录功能')
def transfer():
print('转账功能')
dict1 = {
'0': ['退出', None],
'1': ['登录', login]
}
for key in dict1:
print(key, dict1[key][0])
0 退出
1 登录
有一个列表result嵌套了字典,求出总薪资和平均工资
[{'name': 'wzy', 'sex': 'male', 'age': '18', 'salary': '3000'}, {'name': 'she', 'sex': 'male', 'age': '38', 'salary': '30000'}, {'name': 'tom', 'sex': 'female', 'age': '28', 'salary': '20000'}, {'name': 'jim', 'sex': 'female', 'age': '28', 'salary': '10000'}]
集合
- 字典和集合的key不能重复
- 集合没有value
集合基本语法
交集:
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4}
# 取出交集的2种方法
print(set1 & set2)
print(set1.intersection(set2))
print(set1.isdisjoint(set2)) # 判断是否不相交
并集:
print(set1 | set2)
# 结果
{1, 2, 3, 4}
差集:(去除交集后的元素)
会得到一个空集 {}
,因为集合 set1
中的元素 1
、2
、3
在集合 set2
中都能找到,按照差集的定义,将这些共有元素去除后就没有元素剩下了,所以最终打印输出的结果就是 {}
print(set1.difference(set2))
print(set2-set1)
对称差集:
我有你没有的 加上 你有我没有的
print(set1.symmetric_difference(set2))
print(set1 ^ set2)
结果:
{4}
父子集:
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4}
print(set2 > set1)
结果为:True
集合相关操作
集合去重
l=[
{'name':'lili','age':18,'sex':'male'},
{'name':'jack','age':73,'sex':'male'},
{'name':'tom','age':20,'sex':'female'},
{'name':'lili','age':18,'sex':'male'},
{'name':'lili','age':18,'sex':'male'},
]
new_l=[]
for dic in l:
if dic not in new_l:
new_l.append(dic)
集的2种方法
print(set1 & set2)
print(set1.intersection(set2))
print(set1.isdisjoint(set2)) # 判断是否不相交
并集:
print(set1 | set2)
# 结果
{1, 2, 3, 4}
差集:(去除交集后的元素)
会得到一个空集 {}
,因为集合 set1
中的元素 1
、2
、3
在集合 set2
中都能找到,按照差集的定义,将这些共有元素去除后就没有元素剩下了,所以最终打印输出的结果就是 {}
print(set1.difference(set2))
print(set2-set1)
对称差集:
我有你没有的 加上 你有我没有的
print(set1.symmetric_difference(set2))
print(set1 ^ set2)
结果:
{4}
父子集:
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4}
print(set2 > set1)
结果为:True
集合相关操作
集合去重
l=[
{'name':'lili','age':18,'sex':'male'},
{'name':'jack','age':73,'sex':'male'},
{'name':'tom','age':20,'sex':'female'},
{'name':'lili','age':18,'sex':'male'},
{'name':'lili','age':18,'sex':'male'},
]
new_l=[]
for dic in l:
if dic not in new_l:
new_l.append(dic)