3. python基本数据结构

330 阅读11分钟

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 创建列表

列表的数据项不需要具有相同的类型。

创建列表:

注:

  1. np.arange(5) #[0 1 2 3 4] 生成的是numpy类型的数组,不是列表!
  2. 可以用 [num for num in range(5)] 的方法生成列表。
  3. 可以用 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. 索引

索引:

图片.png

反向索引:

图片.png

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 的差集