《Python程序设计(第二版)》第五章冷门点

集合

一般什么时候用集合呢?

就是想要维护一大堆不重复的数据时,就可以用它。比如:做爬虫去网上找图片的链接,为了避免链接重复,可以选择用集合去存储链接地址。

注意:定义空集合时,只能使用v = set(),不能使用 v={}(这样是定义一个空字典)。

关系

s1={2,3,5,7}
s2={1,2,3,4,5,6,7}
print(s1.issubset(s2))#True,s1是s2的子集
s1={2,3,5,7}
s2={1,2,3,4,5,6,7}
print(s2.issuperset(s1))#True,s2是s1的超集

请添加图片描述

运算

独有功能

  1. 添加元素
data = {"刘嘉玲", '关之琳', "王祖贤"}
data.add("郑裕玲")
print(data)
data = set()
data.add("周杰伦")
data.add("林俊杰")
print(data)
  1. 删除元素
data = {"刘嘉玲", '关之琳', "王祖贤","张曼⽟", "李若彤"}
data.discard("关之琳") 
print(data)
  1. 交集
s1 = {"刘能", "赵四", "⽪⻓⼭"}
s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}

s4 = s1.intersection(s2) # 取两个集合的交集 
print(s4) # {"⽪⻓⼭"}

s3 = s1 & s2                 # 取两个集合的交集
print(s3)
  1. 并集
s1 = {"刘能", "赵四", "⽪⻓⼭"}
s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s4 = s1.union(s2)         # 取两个集合的并集  {"刘能", "赵四", "⽪⻓⼭","刘科⻓", "冯乡⻓", }
print(s4)
s3 = s1 | s2               # 取两个集合的并集
print(s3)
  1. 差集
s1 = {"刘能", "赵四", "⽪⻓⼭"}
s2 = {"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s4 = s1.difference(s2)         # 差集,s1中有且s2中没有的值 {"刘能", "赵四"}
s6 = s2.difference(s1)       # 差集,s2中有且s1中没有的值 {"刘科⻓", "冯乡⻓"}

s3 = s1 - s2                  # 差集,s1中有且s2中没有的值
s5 = s2 - s1                  # 差集,s2中有且s1中没有的值

print(s5,s6)

去掉列表中重复元素,按原列表顺序输出无重复元素的列表

mailto=["cc","bbbb","afa","sss","bbbb",'cc','shafa']
addr_to=list(set(mailto))
addr_to.sort(key=mailto.index)
print(addr_to)#['cc', 'bbbb', 'afa', 'sss', 'shafa']

集合的存储原理

请添加图片描述

元素必须可哈希

因存储原理,集合的元素必须是可哈希的值,即:内部通过通过哈希函数把值转换成一个数字。

目前可哈希的数据类型:int、bool、str、tuple,而list、set是不可哈希的。

总结:集合的元素只能是 int、bool、str、tuple 。

l=["21",1,(1,),True]
s=set(l)#这是可以的
l.append([1,2])
s=set(l)#这是不可以的

查找速度特别快

因存储原理特殊,集合的查找效率非常高(数据量大了才明显)。

  • 低:列表和元组因为每个元素都要一一比较直到结束或找出对应值

    user_list = ["武沛齐","alex","李璐"]
    if "alex" in user_list:
        print("在")
    else:
        print("不在")
    
  • 效率高:它只比较了一次哈希值

    user_set = {"武沛齐","alex","李璐"}
    if "alex" in user_set:
        print("在")
    else:
        print("不在")
    

集合里的所有子孙都必须可哈希

data_list = [
    "alex",
    11,
    (11, 22, 33, {"alex", "eric"}, 22),
    [11, 22, 33, 22],
    {11, 22, (True, ["中国", "北京"], "沙河"), 33}#虽然元组里可以套列表,但是作为集合的子孙是不允许的
]

注意:由于True和False本质上存储的是 1 和 0 ,而集合又不允许重复,所以在整数 0、1和False、True出现在集合中会有如下现象:

v1 = {True, 1}
print(v1)  # {True}

v2 = {1, True}
print(v2)  # {1}

v3 = {0, False}
print(v3)  # {0}

v4 = {False, 0}
print(v4)  # {False}

字典

python 3.6 之后字典就有序了
字典中对键值得要求:

  • 键:必须可哈希。 目前为止学到的可哈希的类型:int/bool/str/tuple;不可哈希的类型:list/set/dict。(集合)
  • 值:任意类型。
    字典在处理布尔值和0、1时会遇到和集合相似的问题
data_dict = {
    1: 29,
    True: 5
}
print(data_dict) # {1: 5}

函数

  1. 删除元素:

    • del 语句或 .pop() 方法删除字典中的元素。
    d = {"name": "Alice", "age": 25}
    del d["gender"]
    # 或者
    value = d.pop("age")
    print(d)  # 输出: {'name': 'Alice'}
    print(value)#输出:25
    
  2. 获取所有键:

    • .keys() 方法返回字典中所有键的视图。
      注意:在Python2中 字典.keys()直接获取到的是列表,而Python3中返回的是高仿列表,这个高仿的列表可以被循环显示。
    keys = d.keys()
    print(list(keys))  # 输出: ['name']
    
  3. 获取所有值:

    • .values() 方法返回字典中所有值的视图。
      注意:在Python2中 字典.keys()直接获取到的是列表,而Python3中返回的是高仿列表,这个高仿的列表可以被循环显示。
    values = d.values()
    print(list(values))  # 输出: ['Alice']
    
  4. 获取所有键值对:

    • .items() 方法返回字典中所有键值对的视图。
      注意:在Python2中 字典.keys()直接获取到的是列表,而Python3中返回的是高仿列表,这个高仿的列表可以被循环显示。
    items = d.items()
    print(list(items))  # 输出: [('name', 'Alice')]
    
  5. 字典推导式:

    • 使用字典推导式创建或修改字典。
    new_dict = {k: v.upper() for k, v in d.items()}
    print(new_dict)  # 输出: {'name': 'ALICE'}
    
  6. 更新字典:

    • 使用 .update() 方法或另一个字典更新字典。
      没有的键直接添加;有的键则更新值
    d.update({"age": 30})
    # 或者
    d.update(age=30)
    print(d)  # 输出: {'name': 'Alice', 'age': 30}
    
  7. 字典排序:

    • 使用 sorted() 函数对字典的键、值或项进行排序。
    for k, v in sorted(d.items(), key=lambda item: item[1]):
        print(f"{k}: {v}")
    # 输出: name: Alice
    
  8. 获取字典的默认值:

    • .get(key, default) 方法返回键对应的值,如果键不存在,则返回None
      用索引的方式取值,若键不存在会报错,但可以修改值、添加值、更新值
    print(d.get("age", "Unknown"))  # 输出: 30
    
  9. 清空字典:

    • .clear() 方法清空字典中的所有元素。
    d.clear()
    print(d)  # 输出: {}
    
  10. 设置值

     data = {
         "name": "武沛齐",
         "email": 'xxx@live.com'
     }
     data.setdefault("age", 18)
     print(data)  # {'name': '武沛齐', 'email': 'xxx@live.com', 'age': 18}
     
     data.setdefault("name", "alex")
     print(data)  # {'name': '武沛齐', 'email': 'xxx@live.com', 'age': 18}
    
  11. 按照顺序移除(后进先出)

    info = {"age":12, "status":True,"name":"武沛齐"}
    data = info.popitem() # ("name","武沛齐" )
    
    print(info) # {"age":12, "status":True}
    print(data) # ("name","武沛齐")
    
  • py3.6后,popitem移除最后的值。
  • py3.6之前,popitem随机删除。

存储原理

同集合,不过是对键进行哈希处理
我们已学了很多数据类型,在涉及多种数据类型之间的嵌套时,需注意一下几点:

  • 字典的键必须可哈希(list/set/dict不可哈希)。

    info = {
        (11,22):123
    }
    
    # 错误
    info = {
        (11,[11,22,],22):"alex"
    }
    
  • 字典的值可以是任意类型。

    info = {
        "k1":{12,3,5},
        "k2":{"xx":"x1"}
    }
    
  • 字典的键和集合的元素在遇到 布尔值 和 1、0 时,需注意重复的情况。

  • 元组的元素不可以被替换。

字典可以作为if多路分支的替代写法

计数作用

输入一个字符串,输出每个字符串出现的次数

s=input()
countchar={}
for c in s:
    countchar[c]=countchar.get(c,0)+1
print(countchar)

多项式相加

poly1={98:2,5:-4,2:3,0:1}
poly2={90:7,5:3,2:-3,1:5}
poly3={}
deg=set(poly1)|set(poly2)
for i in deg:
    coeff=poly1.get(i,0)+poly2.get(i,0)
    if coeff!=0:
        poly3[i]=coeff
print(poly3)

嵌套结构

我们把矩阵中既是行最大元素,又是列最小的元素的位置叫鞍点,通过元组表示,请找出任意n阶矩阵的鞍点

n=int(input())
mat=[input().split() for i in range(n)]
rowdic={}
coldic={}
for i in range(n):
    maxa=max(int(mat[i][j]) for j in range(n))
    mina=min(int(mat[k][i] for k in range(n)))
    rowdic.update({(i,j):mat[i][j] for j in range(n) if int(mat[i][j]==maxa)})
    coldic.update({(k,i):mat[k][i] for k in range(n) if int(mat[k][i]==mina)})
dot=list(set(rowdic)&set(coldic))
if dot!=[]:
    print("鞍点位置:",*dot,"鞍点值:",rowdic[dot[0]])
else:
    print("无鞍点")

循环删除

字典循环删除
dic={
    "赵四":"特v检查",
    "刘能":"chbdnsjfd",
    "大脚":"bcvkrjhw",
    "大脑袋":"vcgjshuj"
}
temp=[]
for key in dic.keys():
    if key.startswith("大"):
        temp.append(key)
for key in temp:
    dic.pop(key)
print(dic)
  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值