Python基本数据结构包括:
- 列表:作为栈\队列\可变数组
- 字典:普通字典
- 元组:不可变数组
- 集合
1. 字典
1.1 创建字典
字典由键值对组成:key:value
key:1.键是唯一的,如果重复键,则后面的会替换前面的。2.一个字典中键只能取一种数据类型,例如数字、字符串、元组等。如:'a','b','c'
value:1.值不是唯一的。2.一个字典中值可以取任何数据类型。如:'Lily',18
创建字典:
# 方法一:使用方括号`{}`创建空列表或直接定义包含元素的列表
dict1={'a':1,'b':2,'c':3}
dict2={'name':'Lily','age':18}
# 方法二:使用`dict()`函数
dict3=dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
dict4=dict(sape=4139, guido=4127, jack=4098)
# 方法三:迭代生成字典
dict5={x: x**2 for x in (2, 4, 6)}
创建空字典:
dict6={}
dict7=dict()
1.2 字典的内置函数(熟练记忆)
以dict1,dict2为例:
dict1={'a':1,'b':2,'c':3}
dict2={'name':'Lily','age':18}
1. 计算字典元素个数,即键的总数 len(dict)
print(len(dict1)) #3
2. 返回输入的变量类型,是字典则返回字典类型 type(dict1)
print(type(dict1)) #<class 'dict'>
3. 删除字典中的所有元素 dict.clear()
- dict3=dict1,相当于起别名,dict1和dict3指向同一个地址,改变dict3的内容也在改变dict1的。
- dict3=dict1.copy(),相当于dict3申请一个新的地址,把dict1的内容复制给了dict3。改变dict3的父节点内容不改变dict1的父节点内容。
dict3=dict1.copy()
dict3.clear()
print(len(dict3)) #0
4. 返回指定键的值,如果键不在字典中返回default值 dict.get(key)
print(dict1.get('d')) #None
print(dict2.get('name')) #Lily
print(dict1['d']) #会报错 KeyError: 'd'
print(dict2['name']) #Lily
5. 以列表返回一个字典所有的键 dict.keys()
print(dict1.keys()) #dict_keys(['a', 'b', 'c'])
6. 以列表返回字典中的所有值 dict.values()
print(dict1.values()) #dict_values([1, 2, 3])
7. 以列表返回可遍历的(key,value)元组数组 dict.items()
print(dict1.items()) #dict_items([('a', 1), ('b', 2), ('c', 3)])
8. 删除字典中给定键所对应的值,返回被删除的值 dict.pop(key)
print(dict1.pop('a')) #1
9. 返回并删除字典中的最后一对键值对 dict.popitem()
print(dict1.popitem()) #('c', 3)
10. 添加键值对 dict2[key]=value
dict2['gender']='man'
print(dict2) #{'name': 'Lily', 'age': 18, 'gender': 'man'}
11. 删除键值对 del
del dict2['name']
print(dict2) #{'age': 18, 'gender': 'man'}
1.3 字典常见应用
仍然是dict1,dict2的列表:
dict1={'a':1,'b':2,'c':3}
dict2={'name':'Lily','age':18}
1. 字典中是否存在该key
print('a' in dict1) #True 'a'在key中,判对了
print('a' in dict1.keys()) #True 'a'在key中,判对了
print('d' in dict1) #False 'd'不在key中,判错了
print('c' not in dict1) #False 'c'在key中,判错了
2. 字典中是否存在该value
print(1 in dict1.values()) #True
print('1' in dict1.values()) #False
3. 遍历key值
#法1:直接遍历dict的key对象
for k in dict1:
print(k)
#法2:直接遍历dict的key对象
for k in dict1.keys():
print(k)
4. 遍历Value值
#法1:直接遍历dict的value对象
for v in dict1.values():
print(v)
#法2:通过key获取value
for k in dict1.keys():
#两种方式获取键的值
print(dict1[k])
print(dict1.get(k))
5. 遍历key,value
for k,v in dict1.items():
print(str(k)+":"+str(v))
2. 列表
2.1 创建列表
列表的数据项不需要具有相同的类型。
创建列表:
注:
- np.arange(5) #[0 1 2 3 4] 生成的是numpy类型的数组,不是列表!
- 可以用 [num for num in range(5)] 的方法生成列表。
- 可以用 list(range(5)) 的方法生成列表。
# 方法一:使用方括号`[]`创建空列表或直接定义包含元素的列表
list1 = [1,2,3,4,5]
list2 = ['a','b','c','d']
list3 = [1,2,'a',(2,3)]
# 方法二:使用`list()`函数将其他可迭代对象(如元组、集合、字符串等)转换为列表
list4 = list({1, 2, 3})
# 方法三:迭代生成有序列表
list5 = [num for num in range(5)] # [0,1,2,3,4]
list6 = list(range(5)) # [0,1,2,3,4]
# 方法四:使用`*`操作符生成包含重复元素的列表
list7 = [0] * 10 # 创建一个包含10个0的列表
创建空列表:
stack=list()
#或者 stack=[]
print(type(stack)) # <class 'list'>
print(len(stack)) # 0
将已存在的列表赋值:
复制:
list_new = list1 # 指向同一地址,相当于给原变量起了个别名
list_new = list1[:] # 浅复制,list_new 的浅层元素不会随着修改,但深层会
list_new = copy.copy(list1) # 浅复制,list_new 的浅层元素不会随着修改,但深层会
list_new = copy.deepcopy(list1) # 深复制,list_new 的浅层和深层元素不会随着修改
你也可以声明一个空间:
list_new = [0] * len(list1) # list_new = [0,0,0,0,0]
但是你不能直接将某个列表的值赋给一个带索引的向量:
# 这个 list_new 没有任何数组上的声明,因此这样写是错的
list_new[0] = list1[0]
2.2 列表的内置函数(熟练记忆)
以list1为例:
list1=[1,2,3,4,5]
1. 列表元素个数 len(list)
print(len(list1)) #5
2. 返回列表元素的最大值、最小值 max(list)、min(list)
print(max(list1)) #5
print(min(list1)) #1
3. 将元组转换成列表 list(seq)
seq=(27,'Venzhy','girl')
list3=list(seq)
print(type(list3)) #<class 'list'>
增加
4. 在列表末尾添加新的对象,注:一次只能追加一个元素,即使追加的是列表也作为一个值 list.append(obj)
list1.append(8)
print(list1) #[1, 2, 3, 4, 5, 8]
5. 在列表末尾一次性追加另一个序列的多个值 list.extend(seq)
s=[0,0,0]
list1.extend(s)
print(list1) #[1, 2, 3, 4, 5, 8, 0, 0, 0]
6. 将对象按索引插入列表 list1.insert(index,obj)
list1.insert(1,18)
print(list1)
# 插入前:[1, 2, 3, 4, 5, 8, 0, 0, 0]
# 插入后:[1, 18, 2, 3, 4, 5, 8, 0, 0, 0]
删除
7. 移除列表中的最后一个元素,并返回该元素的值 list1.pop(index)
默认移除列表中最后一个元素:
list1.pop()
print(list1)
# 弹出前:[1, 18, 2, 3, 4, 5, 8, 0, 0, 0]
# 弹出后:[1, 18, 2, 3, 4, 5, 8, 0, 0]
也可以按索引移除某个元素:
list1.pop(2)
print(list1)
# 弹出前:[1, 18, 2, 3, 4, 5, 8, 0, 0]
# 弹出后:[1, 18, 3, 4, 5, 8, 0, 0]
8. 移除列表中某个值的第一个匹配项 list1.remove(obj)
list1.remove(18)
print(list1)
# 移除前:[1, 18, 3, 4, 5, 8, 0, 0]
# 移除后:[1, 3, 4, 5, 8, 0, 0]
9. 清空列表 list.clear()
10. 删除元素 del list[index]
查找
11. 返回某个元素在列表中出现的次数 list.count(obj)
cou1=list1.count(1)
cou6=list1.count(6)
print(cou1) # 1,数字1出现了1次
print(cou6) # 0,数字6出现了0次
统计字符出现的个数或列表内出现的元素次数可以用Counter,返回的是字典类型。key为元素值,value为该元素在列表中的次数。
from collections import Counter
lis=[1,1,1,2,3,3]
cou=Counter(lis)
print(cou) #Counter({1: 3, 3: 2, 2: 1})
12. 从列表中找出某个值第一个匹配项的索引位置 list1.index(obj)
print(list1.index(8)) #5,5是8的索引
修改
13. 反转列表
list1.reverse()
print(list1)
# 反转前:[1, 3, 4, 5, 8, 0, 0]
# 反转后:[0, 0, 8, 5, 4, 3, 1]
14. 对列表进行排序 list.sort()
list1.sort() #默认升序
print(list1) #[0, 0, 1, 3, 4, 5, 8]
list1.sort(reverse=True) #降序
print(list1) #[8, 5, 4, 3, 1, 0, 0]
15. 复制列表 list.copy()
2.3 列表常见应用
列表可以进行索引,切片,加,乘等操作
1. 索引
索引:
反向索引:
2. 切片
每一个维度都可以被切片,切片规则:list[start:end:step]
- start:切片的起始位置。
- end:切片的结束位置,但不包含end(前闭后开),如果没有值的话表示切割到结束为止。
- step:步长,默认取值为1,如果步长为正数的情况表示从左往右,反正若为负数则表示从右往左。
b=[6,3,6,7,8,2,5,4]
b[:] ##单独一个冒号,代表从头取到尾,步长默认为1
#[6, 3, 6, 7, 8, 2, 5, 4]
b[::]##单独两个冒号一样代表从头取到尾,步长默认为1
#[6, 3, 6, 7, 8, 2, 5, 4]
b[::-1]##注意,两个冒号后面是步长,步长为1,故应从右往左取
#[4, 5, 2, 8, 7, 6, 3, 6]
算法例题
例题一:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
- 每个右括号都有一个对应的相同类型的左括号。
来源:力扣(LeetCode) 链接:leetcode.cn/problems/va… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution:
def isValid(self, s: str) -> bool:
if len(s)%2==1:
return False
#创建字典
dict={
')':'(',
']':'[',
'}':'{'
}
#创建栈
stack=list()
for ch in s:
if ch in dict.values():
stack.append(ch)
else: #考虑 "}[" 边界问题考虑好
if stack and stack[-1]==dict[ch]:
stack.pop()
else:
return False
if stack:
return False
else:
return True
例题二:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标 值 target的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
来源:力扣(LeetCode) 链接:leetcode.cn/problems/tw… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashtable={}
for i,num in enumerate(nums):
if target-num in hashtable:
return [hashtable[target-num],i]
else:
hashtable[num]=i
return []
3. 元组
3.1 创建元组
创建元组:
# 方法一:
t = 12345, 54321, 'hello'
print(t) # (12345, 54321, 'hello')
# 方法二:
s = (1, 2, 3, 4, 5)
u = s, t
print(u) # ((1, 2, 3, 4, 5), (12345, 54321, 'hello'))
# 方法三:
my_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
my_tuple = tuple(my_list)
print(my_tuple) # (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
创建只有一个元素的元组
只有一个元素的元组,必须加上逗号
singletp = 'hello',
# 或者 singletp = ('hello',)
print(singletp) # ('hello',)
创建空元组
empty = ()
3.2 元组基本操作
1. 访问元组
my_tuple = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
# 切片
print(my_tuple[0:3]) # (0, 1, 2)
# 元祖的最大最小值
print(max(my_tuple)) # 9
print(min(my_tuple)) # 0
2. 元组不可修改
# 元组不可改变
b = (1, 2, 3, 4, 5)
print(b[0])
# b[0] = 111 报错
3. 元组连接
my_new_tuple = my_tuple + (100, 101, 102)
print(my_new_tuple) # (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 101, 102)
a = (1, 2, 3)
b = (4, 5, 6)
c = a + b
print(c) # (1, 2, 3, 4, 5, 6)
4. 元组复制
a = (1, 2, 3)
d = a * 3
print(d) # (1, 2, 3, 1, 2, 3, 1, 2, 3)
5. 元素是否存在
print(0 in d) # Fals
6. 删除元组
元组的元素值不允许删除,但是可以使用del语句删除整个元组
del my_tuple
4. 集合
4.1 创建集合
创建集合:
set1 = set(['apple', 'orange', 'apple', 'pear', 'orange', 'banana'])
print(set1)
basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
print(basket) # {'orange', 'banana', 'pear', 'apple'}
创建空集合:
empty = set()
# 定义一个空集合必须用 set() 而不是 {},因为 {} 是一个空字典。
4.2 集合基本操作
s = {'a', 'b', 'c'}
1. 添加元素
# 添加元素
s.add('d')
s.add('a')
print(s) # {'c', 'a', 'b', 'd'}
s.update([1, 4], [5, 6])
print(s) # {'c', 1, 4, 5, 'b', 6, 'a', 'd'}
2. 移除元素
s.remove('a')
print(s) # {'c', 1, 4, 5, 'b', 6, 'd'}
s.discard('d')
print(s) # {'c', 1, 4, 5, 'b', 6}
s.pop()
print(s) # {'c', 1, 4, 5, 'b', 6}
3. 计算元素个数
print(len(s)) # 5
4. 清空元素
s.clear()
print(s) # set()
5. 判断元素是否在集合中存在
print('a' in s) # False
6. 集合运算
a = set('abracadabra')
b = set('alacazam')
print(a) # {'d', 'r', 'b', 'c', 'a'}
print(b) # {'l', 'a', 'z', 'm', 'c'}
print(a-b) # {'b', 'd', 'r'} 在 a 不在 b
print(a|b) # {'l', 'a', 'b', 'z', 'r', 'm', 'c', 'd'} # a 和 b 的并集
print(a&b) # {'c', 'a'} a 和 b 的交集
print(a^b) # {'b', 'l', 'z', 'm', 'r', 'd'} a 和 b 的差集