python基础七——dict和set

dict

dict是dictionary简写,英文字典、词典的意思,dict是Python内置的数据类型,定义时使用大括号,里边采用键值对的形式存储数据,具有无序性,它具有极快的查找速度。(跟JavaScript中的对象写法一样)

特点:

1、键必须是唯一的(如数字、字符串、元组),如果key为list列表,将会报错!值不必是唯一的,如果多个重复的键,最后定义的会覆盖前边;

2、值可以是任何数据类型;

3、dict里边的元素是无序的,没有下标,更不能切片!

author = {'name':"lxc",'age':20,'height':170}

dict创建

————————————————————————————————————————————————————————

dict创建方式目前我想到的有三种方式:

# 方法一
dict = {'key':value}

# 方法二
dict = dict( [('key1',value1),('key2',value2),··· ···] ) # {'key1':'value1','key2':'value2'}

# 方法三 
 dict = dict(key = value,key1 = value1,··· ···) # {'key':'value','key1':'value1'}

上边代码,方法二使用内置函数dict创建字典,dict函数参数必须且只能传一个,否则将报错!所以用列表方式,列表里边以元组(也可以使用列表list)方式存放key-value对。

方法三,使用关键字方式创建字典,  关键字创建字典 key 不需要用引号引起来

 

访问dict中的value值

————————————————————————————————————————————————————————

取dict中的value值有多种方式,我们分别来看下:

(1)通过key来获取value值

取字典dict里边数据使用 变量名中括号形式(在js对象中,如果key是一些特殊的变量或者特殊写法时,会使用中括号的形式取值)。

author = {'name':"lxc",'age':20,'height':170}
print(author['name']) # lxc

注意:

为什么dict查找速度这么快呢,因为dict实现原理与查字典一样,先在字典的索引表里查看这个字的(偏旁或部首)对应的页码,然后直接翻到该页,查找效率非常高,且不会随着字典大小效率降低。

而list查找则是从第一页开始找,直到找到那个字为止,所以dict查找效率是非常高效的!

(2)setdefault()

方法来获取key对应的value,如果key不存在,返回None;也可以为不存在的key设置默认值,返回的是设置的默认值。

d = {'name':'lxc','height':170,'age':20}
# print(d['hehe']) # 报错
print(d.get('hehe')) # None
print(d.setdefault('hehe')) # None

# 设置默认值
print(d.setdefault('haha','呆呆君')) # 呆呆君

上边代码, setdefault总会返回一个key对应的value值!!!!还有一个应该注意点:如果setdefault设置了默认值,但是字典中有key-value对,返回的是字典中的value值。

d = {'name':'lxc'}
print(d.setdefault('name','呆呆君')) # 'lxc'

 

————————————————————————————————————————————————————————

增就是向字典里添加数据,除了初始化指定一个以外,还可以通过key来放到字典里:

author = {'name':"lxc",'age':20,}
author['height'] = "170"
author['height'] = '180'
print(author) #{'name': 'lxc', 'age': 20, 'height': '180'}

上边我们 放入了两个相同的key,最后打印的是最后一次存放进去的key-value,说明后进去的会覆盖前一个。

如果取一个不存在的key,会报错!!!

author = {'name':"lxc",'age':20,}
print(author['height']) # 报错

有两种方法可以检查key是否存在:

方法一:in  返回的是bool值  True或者False

author = {'name':"lxc",'age':20}
print('height' in author) # False

方法二:get ( )  如果一个不存在的key,返回的是None空值,或者是自己指定的值,可以理解为默认值

author = {'name':'lxc','age':20}
print(author.get('height')) # None
print(author.get('height','170')) # 170

这里要说明下,使用中括号访问字典中不存在的key,会报错,但是get( ) 返回是None,相当于增强版的方括号语法。

 

————————————————————————————————————————————————————————

1、pop( )

想要删除字典中的key,用pop(key)方法,此方法返回的是key对应的value值,字典dict中key所对应的value也会被删除。

author = {'name':'lxc','age':20}
print(author.pop('age')) # 20
print(author) # {'name':'lxc'}

2、clear( )

清空字典所有的key-value对,之后字典会变成空字典

判断key是否存在

判断指定的key是否在dict中,可以使用in 或者not in ,in 或not in运算符都是基于key来判断的。

d = {'name':'lxc','age':20}
print('name' in d) #True

 

items、keys、values

这三个方法很神奇,着重把遍历俩字标红,这三个方法本身自带遍历

items遍历字典中的每一个键值对;

keys遍历字典中的键key;

values遍历字典中的value值。

但是python不希望用户直接操作这几个方法,但是可以使用list函数把它们转换成列表。。。

d = {'name':'lxc','age':20,'height':170}
print(list(d.keys())) # ['name','age','height']
print(list(d.values())) # ['lxc',20,170]
print(list(d.items())) # [('name','lxc'),('age',20),('height',170)]

上边代码,三个方法返回值都是list,items方法输出的结果正是上边创建字典dict第三种方法。

上边三个方法一个和for循环一起使用:

补充下:

上边写法通常会返回一组数据,难道你还要循环列表才能拿到单个数据吗?如果你想得到单个数据可以用序列解包

# keys()
d = {'name':'lxc','age':20}
x,y = d.keys()
print(x) # 'name'
print(y) # 'age'

# values()
d = {'name':'lxc','age':20}
x,y = d.values()
print(x) # 'lxc'
print(y) # 20

# items()
d = {'name':'lxc','age':20}
x,y = d.items()
print(x) #('name', 'lxc')
print(y) #('age', 20)

 

dict.fromkeys( )

使用给定的key创建一个字典,如果只有一个参数,key对应点额value值是None;也可以设置默认value值:

#字符串
str = 'abc'
d = dict.fromkeys(str)
print(d) # {'a': None, 'b': None, 'c': None}

#字典
dict = {'name':'lxc','age':20}
d = dict.fromkeys(dict)
print(d) # {'name': None, 'age': None}

#列表
list = [1,2,3]
d = dict.fromkeys(list)
print(d) # {1: None, 2: None, 3: None}


#元组
temple = (1,2)
d = dict.fromkeys(temple)
print(d) # {1: None, 2: None}

设置默认value值:

#列表
list = [1,2,3]
d = dict.fromkeys(list,'lxc')
print(d) # {1: 'lxc', 2: 'lxc', 3: 'lxc'}

补充下:fromkeys()第一个参数也可以是单个值

for i in [list(range(1,5))]:
    r = dict.fromkeys(i,'lxc')
    print(r) # {1: 'lxc', 2: 'lxc', 3: 'lxc', 4: 'lxc'}

再来看个小demo:

利用字典中key不可重复特性,去重列表元素:


li = []
while True:
    n = input('input')
    li.append(n)
    if n == ' ':
        break
for i in li:
    d = dict.fromkeys(li,'lxc')
    r = list(d.keys())
print(r)
# 方法二:
a = [1,1,4,2,6,2]
newa = []
d = {}
for i in a:
    if not d.get(i):
        d[i] = i
        newa.append(i)
print(newa) #[1, 4, 2, 6]

二、利用字典特性,输出列表中各个元素出现的次数:

l = [1,1,1,2,2,3,3,3]
d = {}
for i in l:
    if i in d:
        d[i] += 1
    else:
        d[i] = 1
print(d) # {1: 3, 2: 2, 3: 3}

上边代码,先遍历列表,判断每一个元素是否在字典里;如果数据是字符串,用count方法;如果是元祖跟上边一样。

更简单的写法:

setdefault()对于dict中不存在的key,它会赋值为None

t = ('a', 'a', 'd', 'v', 'd')
d = {}
for k in t:
    d.setdefault(k, 0)
    d[k] += 1
print(d)

# 在简化写法:

t = ('a', 'a', 'd', 'v', 'd')
d = {}
for k in t:
    d[k] = d.setdefault(k, 0) + 1
print(d)

 

三、查看字符串中敏感词出现多少次,并且替换所有敏感词:

# 字符串
s = '''
能够证明申请人或其家人有足够的经历能力负担申请人在西班牙停留及归国费用的文件(银 行证明,财产所有权
    证明等)。最低金额是每月达到IPREM(公共收入指标)的100%:2018年 IPREM为537,84欧元(之后每年查询)。为承担
    家人的生活费用,每月金额为第一位家人IPREM 的75%,其余的每位各IPREM的50%。如申请人有奖学金,其金额计算在收入内。如
    有必要我们会 要求申请人提交其交付全额学费的证明。不接受本年存入的定期存款。(父母两个人的每月活期流 水不少于9000人民
    币,资产证明最好是父母的资产,不要是自己的或其他亲戚的。请尽早做流水 账,不要存现金,也不要一下子转进大额款项以防无
    法证明来源,如果有固定资产也可以提供,比 如房产,车产。  
'''
# 把敏感词定义在字典里
sensitivity = {1:'最好',2:'最低',3:'第一'}
d = {}
for i in sensitivity.values():
    if i in s:
        d[i] = s.count(i)
        s = s.replace(i, '<<<<<flag>>>>>>')
print(d)
print(s) 

# {'最好': 1, '最低': 1, '第一': 1}
'''
能够证明申请人或其家人有足够的经历能力负担申请人在西班牙停留及归国费用的文件(银 行证明,财产所有权
    证明等)。<<<<<flag>>>>>>金额是每月达到IPREM(公共收入指标)的100%:2018年 IPREM为537,84欧元(之后每年查询)。为承担
    家人的生活费用,每月金额为<<<<<flag>>>>>>位家人IPREM 的75%,其余的每位各IPREM的50%。如申请人有奖学金,其金额计算在收入内。如
    有必要我们会 要求申请人提交其交付全额学费的证明。不接受本年存入的定期存款。(父母两个人的每月活期流 水不少于9000人民
    币,资产证明<<<<<flag>>>>>>是父母的资产,不要是自己的或其他亲戚的。请尽早做流水 账,不要存现金,也不要一下子转进大额款项以防无
    法证明来源,如果有固定资产也可以提供,比 如房产,车产。  
'''

 

 

 

补充)使用dict格式化字符串:

在字符串中格式化变量,之前文章讲过,但是假如是字典类型的数据呢,你会把value值挨个遍历出来,然后放在依次放入字符串模板中,好麻烦!!!在dict中,可以在字符串中使用key指定变量,这样就不需要做大量循环工作!

str = '姓名:%(name)s,毕业于:%(school)s,班级:%(class)d'
d = {'name':'鸡小西','school':'鸡西小学','class':2}
print(str % d) #姓名:鸡小西,毕业于:鸡西小学,班级:2

上边代码,在字符串模板中使用key,可以非常方便的输出想要的结果。。。

 

来个小demo:输入N个任意字母,输出每个字母重复了多少次:

dic = {}
r = input('请输入大写字母:')
for i in r:
    res = r.count(i)
    dic[i] = res
for i in dic:
    str = '%s出现了%d次' % (i,dic[i])
    print(str)

 

 

dict与list对比

————————————————————————————————————————————————————————

     1、dict查找和插入的速度极快,也不会随着key的增加效率变慢

     2、需要占用大量的内存,内存浪费多

     3、而list则相反,查找速度慢,会随着key的增加而效率变的更慢

     4、但是list占用空间小,内存浪费很少

     5、dict是以内存来换取时间,list正好相反!

     6、字典dict允许对不存在的key直接赋值,但是列表list不是允许的否则将会报错!!!

这里要注意:

在dict中,key必须是不可变的对象,因为dict是根据key来计算value的存储位置,这个通过key来计算位置的算法叫做哈希算法。

使用字符串或者数字作为key都可以,因为字符串和数字、元组 都是不可变的。。。而list是可变的,不可以作为key来使用。。。

# dict
d = {'name':'lxc'}
d['age'] = 20
print(d) # {'name':'lxc','age':20}

#list
l = [1,2]
l[3] = 1
print(l) # IndexError: list assignment index out of range
# 列表分配索引超出范围

 

 

set

set和dict类似,也是key的组合,但是没有value,而且key不能有重复。(在ES6中,新的数据结构set与python中的set类似,没有value和重复值,只不过需要用new Set()来定义)

set = {1,2}
print(type(set)) # <class 'set'>

创建

创建一个set,需要提供一个list作为集合

mySet = set([1,2,3,2,3])
print(mySet)  # {1,2,3}

上边代码,重复的值会被自动过滤掉。

也可以创建一个空集合

set = set()
print(len(set)) # 0

向set中添加数据,使用add(key)可以重复添加,但是没有任何效果!

mySet = set([1,2,3])
mySet.add(4)
mySet.add(4)
print(mySet)  # {1,2,3,4}

删除set中的某个元素

mySet = set([1,2,3])
mySet.add(4)
mySet.remove(4)
print(mySet)  # {1,2,3}

遍历

可以用for循环来遍历set

mySet = set([1,2,3])
mySet.add((1,2,))
for i in mySet:
    print(i) # (1,2)  1  2  3

交集、差集、合并

# 把两个集合交集,得到相同元素,可使用&
set1 = {1,2,3,4}
set2 = {1,2,5}
print(set1 & set2) # {1,2}
# 差集,把两个集合作差,得到相同元素,可使用-
# 差集要注意:把前一个集合中的与后一个集合相同的元素去掉,保留前一个集合的剩下元素
set1 = {1,2,3,4}
set2 = {1,2,5}
print(set1 - set2) # {3,4}
# 合并集合 可以使用 |,就是把两个集合合并只保留一位相同元素
set1 = {1,2,3,4}
set2 = {1,2,5}
print(set1 | set2) # {3,4,5}

set与dict区别

set和dict区别在于,set没有value值,所以set的原理和dict一样,同样也不可以存放可变的key

mySet = set([1,2,3])
mySet.add([123])
print(mySet)  # 报错

总结下:一至七我们聊的是Python的基础数据类型,我们用一张脑图把知识整合下:

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值