python的集合和字典

python的集合和字典基础部分

因为python里面集合set以及字典dict既有联系,又相互区别,所以放在一起谈谈基础的部分



前言

集合(Set)
集合是无序和无索引的集合。在 Python 中,集合用花括号编写。
字典(Dictionary)
字典是一个无序、可变和有索引的集合。在 Python 中,字典用花括号编写,拥有键和值。

注意异同点。都是花括号,但是集合没有键


一、集合字典的定义

一般的声明

这里需要仔细观察一下结果,如下:

set1 = {"唐僧","悟空","八戒","沙僧"}
thisset = set(("apple", "banana", "cherry")) # 从元组转换而来
thisset = set(["apple", "banana", "cherry"]) # 从列表转换而来
thisset = set("apple", "banana", "cherry") # 这个是非法的!!!
dict1 = {1:"唐僧",2:"悟空",3:"八戒",4:"沙僧"} # : 作为键,不是等号
print(set1)
print(dict1)

字典的键要求只能是数字和字符串,不要求类型一致,只要合法,实际上最后都是按类似字符串处理。我的观点是,只记住字符串最好。因为这样和其他的语言一起理解才方便。对应的值的类型没有具体的要求,也不需要同一类型。

# 第一次输出
{'八戒', '唐僧', '沙僧', '悟空'}
{1: '唐僧', 2: '悟空', 3: '八戒', 4: '沙僧'}
# 第二次输出
{'悟空', '沙僧', '八戒', '唐僧'}
{1: '唐僧', 2: '悟空', 3: '八戒', 4: '沙僧'}

我们已经知道如果是[]的列表那么就是按照原样顺序输出的。
但是我们发现集合每次输出的结果顺序都不一样。集合倒无所谓,反正是来做逻辑运算的,
而且如果需要顺序的话转换为list排序就行。
关键的是字典虽然显示是有序的,但那个只是表象,可能和具体的底层实现有关。也就是说,
虽然字典看上去有序,但是实际上是无序的
有序字典的实现和使用见第三点。

空集合,字典的声明

weizhi = {}
set2 = set()
dict2 = dict()
set3 = set(dict())
print(type(weizhi))
print(type(set2))
print(type(dict2))
print(type(set3))

结果如下:

<class 'dict'>
<class 'set'>
<class 'dict'>
<class 'set'>

我想说的是可能是字典是python创始人吉多·范罗苏姆(Guido van Rossum)的私生子
所以{}的声明留给了空字典,而没有给空集合。所以空集合只能set(),或者像第四个一样类型转换,不过明显这是脱裤子放屁之举。。。
在这里插入图片描述

字典的扩展(中级)

我们尝尝需要字典满足两种功能

  1. 满足初始化的插入顺序
  2. 对没有键的数据也能进行处理。

OrderedDict

from collections import OrderedDict
dic = OrderedDict()
dic['name'] = 'maple'
dic['age'] = '18'
dic['weight'] = '70'
print(dic) #OrderedDict([('name', 'maple'), ('age', '18'), ('weight', '70')])

# move_to_end('name') 移动指定的键值对到最后
dic.move_to_end("name")
print(dic) #OrderedDict([('age', '18'), ('weight', '70'), ('name', 'maple')])

# 其他方法与普通字典一样
print(dic.update({"heigh":"17"}))
print(dic.pop("age"))
print(dic.popitem())
print(dic.items())
print(dic.keys())
print(dic.values())

注释数据类型本质上的改变了,主要是接口都是一样的所以可以像普通字典那样各种使用

defaultdict

python生成的字典在 dict[key]取值时如果key不存在会报错
所以这种情况下有两种思路,第一个,if判断,特殊处理。第二个就是默认初始化,
其实这两个思路异曲同工。

from collections import defaultdict
# list 第一次返回空列表,可以实现数据合并
s = [('red', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
# 求同样的键对应的值,相当于按键聚类
d = defaultdict(list)
for k, v in s:
    d[k].append(v)
print(d)
# defaultdict(<class 'list'>, {'red': [1, 1], 'blue': [2, 4], 'yellow': [3]})
# 求同样的键出现的次数
d = defaultdict(int)
for k, v in s:
    # print(k)
    # print(d[k])
    d[k] += 1
print(d)
# defaultdict(<class 'int'>, {'red': 2, 'blue': 2, 'yellow': 1})

其实说白了,就是在键未知的情况下去进行操作的时候(一般就是添加)要合理(自动化初始键)
那么值的初始化是什么呢?d = defaultdict(list)依据声明中的类型,比如这里就是列表,所以才能有append操作。int默认是0。str默认是空字符串"".。当然咯还可以是自定义的对象。

二、索引

1.集合的索引

thisset = {"apple", "banana", "cherry"}

for x in thisset:
  print(x)

注意set是没有[]操作的也就是说thisset[0]是绝对不可行的。而且就算可行,请问没有顺序的情况下序号怎么对应呢?

2.字典的索引

字典在其他语言中可能成为关联列表。
很明显的说来就是按内容访问的。也就是键!

代码如下(示例):

thisdict =	{
  "brand": "Porsche",
  "model": "911",
  "year": 1963
}
print(thisdict)
x = thisdict["model"]
x = thisdict.get("model")

建议采用[]都是这个爽。

字典的遍历有好几种。

# 打印键
for x in thisdict:
  print(x)
# 打印键
for x in thisdict.keys():
  print(x)
# 打印值
for x in thisdict.values():
  print(x)

# 打印值
for x in thisdict:
  print(thisdict[x])
# 一起打印键值
for x, y in thisdict.items():
  print(x, y)

三,增删

集合的增删

问一个小问题集合内的元素可以修改吗?
必然不可以啦,同志们。都不知道是哪一个,改个锤子!!!

thisset = {"apple", "banana", "cherry"}
# 添加一个 add
thisset.add("orange")

print(thisset)
# 添加多个 update
thisset = {"apple", "banana", "cherry"}

thisset.update(["orange", "mango", "grapes"])

print(thisset)
# 删除 remove,如果要删除的项目不存在,则 remove() 将引发错误
thisset = {"apple", "banana", "cherry"}

thisset.remove("banana")

print(thisset)

thisset = {"apple", "banana", "cherry"}
# 删除 discard,如果要删除的项目不存在,则 discard() 不会引发错误
thisset.discard("banana")

print(thisset)
# pop,我倒是觉得产生随机数挺好,对于删除而言没有意义。
thisset = {"apple", "banana", "cherry"}

x = thisset.pop()

print(x)
# clear() 方法清空集合
print(thisset)
thisset = {"apple", "banana", "cherry"}

thisset.clear()
# del 彻底删除集合
print(thisset)
thisset = {"apple", "banana", "cherry"}

del thisset

print(thisset)

我们经常会在逻辑运算之后将set转换为list。list才是非关联状态下的核心数据结构!!!

字典的增删

字典是可以索引的自然也是可以修改的。

thisdict =	{
  "brand": "Porsche",
  "model": "911",
  "year": 1963
}
thisdict["year"] = 2019
# 增加一对关系
thisdict["color"] = "red"
print(thisdict)
# popitem删除最后一个
thisdict.popitem()
print(thisdict)
# 删除一对关系
del thisdict["model"]
# 删除整个字典
del thisdict
#clear
thisdict.clear() # {}

从字典的增删我们可以看到,对于字典而言键和值,键是占绝对主导地位的。
所以运用字典的时候我们需要首先考虑我用什么来做键。

补充:字典是一切关联关系的基础,所以对象的本质就是字典。这一点可以类似cpp的struct。

必须掌握的操作

集合

集合的操作主要体现在逻辑运算方面,可以辅助韦恩图理解:

x = {"apple", "banana", "cherry"}
y = {"google", "microsoft", "apple"}
 # difference 返回一个集合,其中包含仅存在于集合 x 中而不存在于集合 y 中的项目
z = x.difference(y) 
print(z)
# isdisjoint,所有集合 x 中没有项目存在于集合 y 中,则返回 True
z = x.isdisjoint(y) 
print(z)
# issubset,如果集合 y 中存在集合 x 中的所有项目,则返回 True
x = {"a", "b", "c"}
y = {"f", "e", "d", "c", "b", "a"}

z = x.issubset(y) 
# issuperset,假如集合 y 中的所有项目都存在于集合 x 中,则返回 True
x = {"f", "e", "d", "c", "b", "a"}
y = {"a", "b", "c"}
z = x.issuperset(y) 
# union交集
x = {"apple", "banana", "cherry"}
y = {"google", "microsoft", "apple"}

z = x.union(y) # 可以多个逗号隔开
# symmetric_difference差集
x = {"apple", "banana", "cherry"}
y = {"google", "microsoft", "apple"}

z = x.symmetric_difference(y) 
# 当然我们一般用简化符号计算,效果和对应的函数相同
set1 = aset&bset	#交集运算
set2 = aset|bset	#并集运算
set3 = aset-bset	#差集运算
set4 = aset^bset	#补集运算

字典

# in
thisdict =	{
  "brand": "Porsche",
  "model": "911",
  "year": 1963
}
if "model" in thisdict:
  print("Yes, 'model' is one of the keys in the thisdict dictionary")

# len()
print(len(thisdict))

# 复制,这是重点
'''
您不能通过键入 dict2 = dict1 来复制字典,因为:dict2 只是对 dict1 的引用,
而 dict1 中的更改也将自动在 dict2 中进行。
您不能通过键入 dict2 = dict1 来复制字典,因为:dict2 只是对 dict1 的引用,而
 dict1 中的更改也将自动在 dict2 中进行。
'''
# copy,潜复制
thisdict =	{
  "brand": "Porsche",
  "model": "911",
  "year": 1963
}
mydict = thisdict.copy()
print(mydict)
# dict,新建副本,深复制
thisdict =	{
  "brand": "Porsche",
  "model": "911",
  "year": 1963
}
mydict = dict(thisdict)
print(mydict)

# cmp,两个字典的比较,一般只有键一样的时候,比较值
dict1 = {'Name': 'Zara', 'Age': 7};
dict2 = {'Name': 'Mahnaz', 'Age': 27};
dict3 = {'Name': 'Abid', 'Age': 27};
dict4 = {'Name': 'Zara', 'Age': 7};
print "Return Value : %d" %  cmp (dict1, dict2)
print "Return Value : %d" %  cmp (dict2, dict3)
print "Return Value : %d" %  cmp (dict1, dict4)

总结

集合和字典本身都是一种集合。
只不过集合存储的是单一的元素,字典存储的是关联关系。如果有重复的值一般而言都是后面的覆盖前面的。所以请千万确定键的合理性。

提醒一句。python如果你不知道用什么存储结构。那么简单,你记得住对应位置上的内容,就用list
,记不住就用字典。。。大部分就这两个二选一。。。
在这里插入图片描述

字典的具体实操部分以后和各位同学分享!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

演技拉满的白马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值