三、字典(dict)
1.字典的创建
- 赋值创建字典
In [2]: d = {1,True,"hello"}
In [3]: type(d)
Out[3]: set
#字典由key和value构成,一个key对应一个value,key-value , 键值对
In [4]: d = {1:"freya",2:"lili",3:"lucy"}
In [5]: type(d)
Out[5]: dict
In [6]: print d
{1: 'freya', 2: 'lili', 3: 'lucy'}
- 通过工厂函数创建字典
#通过字典的dict()方法创建
In [17]: d = dict(user= "freya",)
In [18]: userinfo = dict(user1="123", user2="456", user3 ="789")
In [19]: print userinfo
{'user2': '456', 'user3': '789', 'user1': '123'}
# 通过字典的 fromkeys 方法创建字典,所有元素有一个默认值
# 如果没有指定默认值,默认为 None;
print {}.fromkeys("hello")
{'h': None, 'e': None, 'l': None, 'o': None}
# 给每个元素设置默认值为 "123";
print {}.fromkeys(["user1", "user2", "user3"], "123")
{'user2': '123', 'user3': '123', 'user1': '123'}
应用案例: 生成多个银行卡号,并初始化密码为”000000”
# 卡号由 6 位组成, 前 3 位是 610 , 后面的依次是 001, 002, 003...100
cardids = []
for i in range(1, 10): # i = 1, 2, 3, 4...100
a = "610%.3d" %(i) # a= 610001, 610002, 610003, ....610100
cardids.append(a)
print {}.fromkeys(cardids, "000000")
2.分析字典的特性(跟元组和列表比较)
- 字典不能索引和切片,因为字典是无序的数据类型
- 字典不支持重复和连接
- 字典支持成员操作符: 判断字典的key值是否在字典中存在
In [25]: userinfo = dict(user1="123", user2="456", user3 ="789")
In [26]: "user1" in userinfo
Out[26]: True
In [27]: "123" in userinfo #由于是判断字典的key值是否在字典中,而该语句判断的是value,故返回false
Out[27]: False
3.字典的增删改查
(1)增
- 字典名[key] = value
###value的数据类型为字符串
In [30]: d = {1:"freya",2:"lili"}
In [31]: d[3] = "lucy"
In [32]: print d
{1: 'freya', 2: 'lili', 3: 'lucy'}
###字典内的value的数据类型也为字典的情况
In [36]: d = {"freya":{1:"freya"},"lili":{2:"lili"}}
In [37]: d["lucy"] = {3:"lucy"}
In [38]: print d
{'lili': {2: 'lili'}, 'lucy': {3: 'lucy'}, 'freya': {1: 'freya'}}
- update()方法
update 方法实现添加: key 存在,覆盖 value 值, 否则,就是添加
语法格式:
字典名.update(key=value)
字典名.update({key:value})
In [46]: print d
{'lili': {2: 'lili'}, 'freya': {1: 'freya'}}
#使用update的方法可以添加多个键值对,注意:键不打引号
In [47]: d.update(tom={4:"tom"},peter={5:"peter"})
In [48]: print d
{'peter': {5: 'peter'}, 'lili': {2: 'lili'}, 'freya': {1: 'freya'}, 'tom': {4: 'tom'}}
setdefault() 实现添加: key 存在,不覆盖 value 值, 否则,添加
语法格式:字典名.setdefault(key,value)
#key存在,不覆盖value
In [52]: print d #刚开始的d的key-value
{'peter': {5: 'peter'}, 'lili': {2: 'lili'}, 'freya': {1: 'freya'}, 'tom': {4: 'tom'}}
In [53]: d.setdefault("peter",{7:"peterr"})
Out[53]: {5: 'peter'}
In [54]: print d #无变化
{'peter': {5: 'peter'}, 'lili': {2: 'lili'}, 'freya': {1: 'freya'}, 'tom': {4: 'tom'}}
#key不存在,覆盖value
{'peter': {5: 'peter'}, 'lili': {2: 'lili'}, 'freya': {1: 'freya'}, 'tom': {4: 'tom'}} #刚开始的d的key-value
In [56]: d.setdefault("happy",{7:"happy"})
Out[56]: {7: 'happy'}
In [57]: print d #添加成功
{'happy': {7: 'happy'}, 'peter': {5: 'peter'}, 'lili': {2: 'lili'}, 'freya': {1: 'freya'}, 'tom': {4: 'tom'}}
(2)删
以字典名d为例
- d.pop(key) 删除指定 key 的字典元素
- d.popitem()随机删除字典的 key-value 元素
- del d[key]删除指定 key 的字典元素;
- d.clear()清空字典元素
(3)查
- 查看key值
In [60]: services = {'ftp': 22, 'http': [80, 8080]}
In [61]: services.keys()
Out[61]: ['ftp', 'http']
- 查看value值
In [62]: services = {'ftp': 22, 'http': [80, 8080]}
In [63]: services.values()
Out[63]: [22, [80, 8080]]
- 查看key-value键值对
In [65]: services = {'ftp': 22, 'http': [80, 8080]}
In [66]: services.items()
Out[66]: [('ftp', 22), ('http', [80, 8080])]
- 查看key是否存在
# 查看 key是否存在
In [67]: services = {'ftp': 22, 'http': [80, 8080]}
In [68]: services.has_key('ftpp')
Out[68]: False
#查看指定 key 对应的 value 值
In [71]: services = {'ftp': 22, 'http': [80, 8080]}
In [72]: services["ftp"] #当key存在,返回 value 值
Out[72]: 22
In [73]: services["tp"] #当key不存在,直接报错
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-73-51d7e8789a37> in <module>()
----> 1 services["tp"]
KeyError: 'tp'
##解决该问题可以使用
services.get(key) 如果 key 不存在,不报错; 如果存在,返回 value 值
(4)改(类似与增)
- 字典名[key]=value
- 字典名.update({key:value})
- 字典名.update(key=value)
4.字典元素循环遍历字典
#遍历字典的key-value
services = {'ftp': 22, 'http': [80, 8080]}
for i,j in services.items():
print i,j
#运行效果:
ftp 22
http [80, 8080]
#默认情况下遍历字典的 key 值
services = {'ftp': 22, 'http': [80, 8080]}
for i in services:
print i
#运行效果:
ftp
http
5.字典应用
(1).由于目前python不支持case语句,实现case语句的两种方式,以实现四则运算为例
- if…elif…elif…else…
print """
实现四则运算
用户分别输入第一个数字,运算操作符,第三个数字;
根据用户的运算操作打印出运算结果;
"""
num1 = input("num1:")
ope = raw_input("operator:")
num2 = input("num2:")
# case 语句
if ope == "+":
print num1+num2
elif ope == "-":
print num1-num2
elif ope == "*":
print num1*num2
elif ope == "/":
print num1/num2
else:
print "error operator"
- 字典实现
print """
实现四则运算
用户分别输入第一个数字,运算操作符,第三个数字;
根据用户的运算操作打印出运算结果;
"""
num1 = input("num1:")
ope = raw_input("operator:")
num2 = input("num2:")
# case 语句
d = {
"+" :num1+num2,
"-" :num1-num2,
"*" :num1*num2,
"/" :num1/num2,
}
if not ope in d:
print "error operator"
else:
print d[ope]
(2)用户登录管理系统
详见我的用户管理系统这篇博客
四、集合(set)
1.集合的两个功能:
集合可以实现去重的功能;
集合可以实现关系测试; 交集, 差集,并集, 是否子集, 是否没有交集……..
2.集合的创建
- 集合是不重复的数据结构
# 如果花括号里面为空,则是字典类型
s = {}
print type(s)
<type 'dict'>
s = {1, 2, 3, 2, 3}
print type(s)
print s
运行效果:
<type 'set'>
set([1, 2, 3])
- 工厂方法定义集合时, 括号里面是可迭代的对象, eg: 数值类型不可以
#定义一个空的集合
s = set()
#集合内的成员可以是字符串、字典、元组、列表这些可迭代对象
s1 = set("hello")
print s1
s2 = set({'a':1, 'b':2, 'c':3})
print s2
s3 = set((1,2,3,4,5))
print s3
s4 = set([1,2,3,1,2,3])
print s4
运行结果:
set(['h', 'e', 'l', 'o'])
set(['a', 'c', 'b'])
set([1, 2, 3, 4, 5])
set([1, 2, 3])
我么发现这些输出都没有重复的地方,这便体现了集合的第一个功能:去重
tips: 实现列表去重?转换为集合数据类型
- set(列表)
li = [1, 2, 3, 4, 1, 2]
s = set(li)
li = list(s)
print li
运行效果:
[1, 2, 3, 4]
- 字典的fromkeys方法实现
li = [1, 2, 3, 4, 1, 2]
d = {}.fromkeys(li)
print d.keys()
运行效果:
[1, 2, 3, 4]
3.集合的特性
- 集合是无序的, 不重复的数据类型
- 因此不支持索引,也不支持切片;也不支持重复;也不支持连接
- 支持成员操作符
- 支持for循环,是可迭代的对象
4.集合的增删差改
- 增
###使用add()方法
s = {1, 2, 3, 4, 1, 2}
print s
s.add(1) #当添加的是重复的元素,添加失败
s.add(7) #当添加的不是重复的元素,添加成功
print s
运行效果:
set([1, 2, 3, 4])
set([1, 2, 3, 4, 7])
###使用update()方法
s1 = {'a', 'b', 'c'}
s.update(s1)
print s
运行效果:
set(['a', 1, 2, 3, 4, 7, 'c', 'b'])
- 删
(1)pop方法的含义是删除随机一个元素,若集合为空,则产生错误。
s = {1, 2, 3, 4, 1, 2}
s.pop()
print s
运行结果:
set([2, 3, 4])
(2)remove方法删除集合指定元素, 如果不存在,则报错。
s = {1, 2, 3, 4, 1, 2}
s.remove(2)
print s
运行结果:
set([1, 3, 4])
(3)discard方法删除集合指定元素, 如果不存在,do nothing;
s = {1, 2, 3, 4, 1, 2}
s.discard(7)
print s
运行结果:
set([1, 2, 3, 4])
(4)clear方法是清空集合元素
s = {1, 2, 3, 4, 1, 2}
s.clear()
print s
运行效果:
set([])
- 查- (关系测试操作)
s1 = {1, 2, 3, 4}
s2 = {1, 2, 3, 5}
# 交集
print s1 & s2 or s1.intersection(s2)
# 并集
print s1 | s2 or s1.union(s2)
# 差集
print s1 - s2 or s1.difference(s2) #s1中有,s2中没有的元素
print s2 - s1 or s2.difference(s1) #s2中有,s1中没有的元素
# 对等差分,s1和s2的并集减去公共的部分后的元素
print s1 ^ s2 or s1.symmetric_difference(s2)
运行结果:
set([1, 2, 3])
set([1, 2, 3, 4, 5])
set([4])
set([5])
set([4, 5])
#判断两个集合的关系
s1.issubset(s2) #判断s1是否为s2的子集
s1.issuperset(s2) #判断s1是否为s2的父集
s1.isdisjoint(s2) #判断s1和s2是否没有交集
- 改
类比增(不赘述)
应用
(华为机试题)题目描述
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性, 他先用计算机生成了N个1到1000之间的随机整数(N≤1000), N是用户输入的,对于 其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应 着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺 序去找同学做调查。请你协助明明完成“去重”与“排序”的工作
代码如下:
s = set()
N = input('输入一个数:')
for i in range (N) :
s.add(random.randint(1,1000))
# sorted 是内置方法, 用来排序;
print sorted(s)
运行效果:
输入一个数:9
[408, 422, 476, 525, 586, 651, 722, 735, 959]
五、小结
我们在介绍里数值类型的数据,以及字符串、元组、列表、字典、集合后来对他们的特性做以下总结
- 可变数据类型: 列表, 字典, 集合
不可变数据类型: 数值类型, 字符串, 元组
可变数据类型实现某个功能, 直接改变可变的数据类型
不可变数据类型实现某个功能,需要将结果赋值给另外一个变量是否实现for循环(是否为可迭代数据类型)
可迭代数据类型: str, list, tuple, dict, set
不可迭代数据类型:数值类型是否支持索引,切片, 重复和连接特性
有序的数据类型: str, list, tuple
无序的数据类型: dict, set
ok~这篇博客到此结束