Python:映像、集合
一、字典
字典(dictionary)是Python中唯一的“映射”类型,映射这个概念在高中就学过:一个函数f将键(key, 定义域)映射到值(value, 值域)。这样的函数在字典中可以称为哈希(HASH)函数。通过哈希函数可以对键通过计算快速得到值的位置,而避免了线性搜索,极大的提高了数据值的存取效率;此外,字典是容器类型,可更新模型。基于这些特性,字典通常被认为是Python中最强大的数据类型之一。
1.创建和赋值
1
2
3
4
5
6
7
8
9
10
|
dict1 = {} #use curly slice to pack elements #here create an empty dict dict2 = { 'name' : 'earth' , 'port' : 80 } #a dict with two key-value pairs dict3 = dict (([ 'x' , 1 ], [ 'y' , 2 ])) #factory fun dict4 = {}.fromkeys(( 'x' , 'y' ), - 1 ) #builtin fun fromkeys(), all valued -1 dict5 = {}.fromkeys(( 'x' , 'y' )) #all valued default 'None' |
fromkeys()可以使用一个可迭代的序列作为键集合创建一个默认字典,第二个参数是默认值,如果忽略的话所哟value默认为‘None
2.访问
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> dict1 = { 'name' : 'earth' , 'port' : 80 } >>> dict1 #visit dict itself { 'name' : 'earth' , 'port' : 80 } >>> dict1[ 'name' ] #visit single key-value 'earth' >>> for key in dict1.keys(): #use for loop to visit print "key=%s, value=%s" % (key, dict1[key]) key = name, value = earth key = port, value = 80 >>> |
如果你试图访问的键在字典中不存在,则会引发一个异常:
1
2
3
4
5
6
|
>>> dict1['age'] #key 'age' is not existed! Traceback (most recent call last): File "< pyshell #8>", line 1, in < module > dict1['age'] KeyError: 'age' |
所以之前,你最好先判断一下这个键是否存在:
1
2
3
4
|
if 'age' in dict1.keys(): ... else : ... |
3.更新
1
2
3
4
5
6
7
|
dict1[ 'name' ] = 'moon' #update existed item dict1[ 'port' ] = 777 #update existed item dict1[ 'age' ] = 20 #add a new item!! dict1.update(another_dict) #update a dict with another #update() is a builtin method of #dict class |
很简单吧?——如果键已存在,则用新值更新旧值,否则,加入新键值对。
4.删除
1
2
3
4
|
del dict1[ 'name' ] #删除“键”为“name”的条目 dict1.clear() #删除dict1中的所有条目 del dict1 #删除dict1这个字典 dict1.pop( 'name' ) #删除并返回“键”为‘name’的条目 |
二、映射类型操作符,内建函数,工厂函数,内建方法
1.标准类型操作符
=, <, <=, >, >=, ==, !=
字典相互比较的过程和列表、元组一样,都是一对一的比较,直至分出胜负,但不得不说,这里的比较要稍微复杂些,一会会讲到。
2.映射类型操作符
键查找操作符"[ ]"
注意,对于序列类来说,中括号中放置的是索引&下标(index),而对于映射类型,放置在中括号中的是键,或者说是参数,这和索引是不同的,不仅仅是概念上的差异,这涉及到寻址的方式,这里不会详细探讨这些。
成员关系操作符(in, not in)
3.内建函数
type()用于字典会返回其类型:“<type 'dict'>”
str()工厂方法用于字典会返回其字符串表示
cmp()用于字典的比较,算法为:先比较字典大小,elseif键,elseif值,但不得不说,用cmp做字典比较一般不是很有用
len():返回字典键值对的数目
hash():返回一个对象的hash值,它并不是作用于字典,而是作用于其它对象类型,一个可hash的对象可以作为字典的键,这个在后面会讲到的
sorted():作用于字典,可以返回一个对keys排序后的列表,这会经常用得到,但一定要明白的,字典中的键值对本身是无序的,这是和序列类型的一个本质区别
4.工厂函数
dict()作为字典的工厂函数是用来创建字典的,如果参数为空,则创建一个空字典‘{ }’,dict()的参数使用很灵活:
1
2
3
4
5
6
|
>>> dict ( zip (( 'x' , 'y' ), ( 1 , 2 ))) { 'y' : 2 , 'x' : 1 } >>> dict ([[ 'x' , 1 ], [ 'y' , 2 ]]) { 'y' : 2 , 'x' : 1 } >>> dict (x = 1 , y = 2 ) { 'y' : 2 , 'x' : 1 } |
1
2
3
4
|
dict1 = { 'name' : 'earth' , 'age' : 30 } dict2 = dict (dict1) #浅拷贝 dict3 = dict .copy() #浅拷贝,使用内建方法 #第二种方法速度更快!! |
5.映射类型的内建方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
print '''映射类型内建方法 dict.clear() 删除字典中的所有元素,并返回一个浅拷贝的副本 dict.fromkeys(seq, val=None) 以序列seq中的元素作为键,创建并返回一个新字典 val为键值对的默认value dict.get(key, default=None) 对字典中的key,返回value,若key不存在,返回default dict.has_key(key) 判断字典中key是否存在 dict.items() 返回一个包含字典中键值对元组的列表 dict.keys() 返回字典中键的列表 dict.pop(key, [default])和方法get相似,区别在于不仅返回,还要删除 dict.setdefault(key, default=None) dict.update(dict2) dict.values() 返回包含所有value的列表 ''' |
对于不同的数据类型,讲到越往后就越粗糙了,因为很多内容有太多的相似性,你到现在应该可以熟练使用帮助文档了,所以不太清楚的时候多查查文档,这是一个好习惯:
dir(module_name), dir(type), help(module_name || type), module.__doc__ .......
三、字典的键
字典中的值可以是任何Python对象,甚至是字典以及用户自定义类型,但对于键却是有一些限制的。
1.不允许一个键对应多个值
你高中数学没有不及格的话,这个应该清楚的,这是严格的“映射”概念中所要求的。
1
|
dict1 = { 'name' : 'green' , 'age' : 20 , 'name' : 'marry' } |
上例中,出现了两个键‘name’,对于这种冲突,Python直接取最后的赋值,所以,最后得到的是:
1
2
|
>>>dict1 { 'name' : 'marry' , 'age' : 20 } |
2.键必须是可哈希的
可哈希的对象才可以作为键,列表、字典这样的可变类型是不可哈希的,所以不能作为键。所有不可变类型都是可哈希的,所以可以作为字典的键。要说明的是,对于数字类型来说,值相等的数字表示相同的键,1,和1.0的哈希值是相同的,它们是相同的键。
对于可变对象,如果事先了__hash__()方法,方法返回一个整形,那它的hash值也是不变的,因此这类对象可以作为键,这是一种特例。
数字和字符串毫无疑问可以作为键,那么元组呢?(也是不可变类型)。在前面深拷贝和浅拷贝的例子中,我们可以看到,元组并不一定是一成不变的,如果其中某个成员是列表、字典等可变类型,我们仍然可以“改变元组”:
1
2
|
tuple_demo = ( 12 , [ 'a' , 'b' ]) tuple_demo[ 1 ][ 0 ] = 'name' |
所以,我们规定,元组中只包括数字、字符串这样的不可变参数,才可以作为字典中的有效键。
前面提到过hash()函数,使用hash(obj),可以返回对象的hash值,如果返回异常,说明这个对象不能够被hash,你应该明白:它一定不能用作字典的键。
下面的这个例子用于为字典的学习做一个小结:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#!/usr/bin/env python 'userpw.py --管理用于登陆系统的用户信息' db = {} #empty dict, used to record info~ of users def newuser(): prompt = 'login desired:' while True : #get a lawful username not existed name = raw_input (prompt).strip() if db.has_key(name): prompt = 'name taken, try another:' continue else : break #get password pwd = raw_input ( 'passwd: ' ) db[name] = pwd #add item into dict def olduser(): name = raw_input ( 'login: ' ) pwd = raw_input ( 'passwd: ' ) passwd = db.get(name) #passwd is real pwd in db if passwd = = pwd: print 'welcome back' , name else : print 'login incorrect' def showmenu(): prompt = ''' (N)ew User Login (E)xisting User Login (Q)uit Enter Choice: ''' return prompt #main loop start done = False #flag varible used to sign quit state while not done: chosen = False while not chosen: try : choice = raw_input (showmenu()n).strip()[ 0 ].lower() except (EOFError, KeyboardInterrupt): choice = 'q' print '\nYou picked: [%s]' % choice if choice not in 'neq' : print 'invalid option, try again' else : chosen = True if choice = = 'q' : done = True #sign the flag if choice = = 'n' : newuser() if choice = = 'e' : olduser() if __name__ = = '__main__' : showmenu() |
四、集合
集合在现今的主流Python版本中已经是基本数据类型,过去是通过其它类模块(ImmutableSet,Set)实现的。这里的“集合”概念和数学中是相同的,你可以对其进行交、并、差、补等一些列操作。
Python中的集合有两种类型,可变集合(set)和不可变集合(frozenset),对于可变集合,可以添加和删减元素,但不可哈希,因此不能用作字典的key,也不能作为其它集合的元素;而不可变集合可以哈希,可以被用作key或者集合成员。
1.创建集合和赋值
1
2
3
4
5
6
7
8
|
#以下用三种方式创建了三个相同的可变集合 set1 = set ( 'abcde' ) set2 = set (( 'a' , 'b' , 'c' , 'd' , 'e' )) set3 = set ([ 'a' , 'b' , 'c' , 'd' , 'e' ]) #以下用三种方式创建了三个相同的不可变集合 set4 = frozenset ( 'abcde' ) set5 = frozenset (( 'a' , 'b' , 'c' , 'd' , 'e' )) set6 = frozenset ([ 'a' , 'b' , 'c' , 'd' , 'e' ]) |
2.访问集合成员
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> myset = set ([ 'apple' , 'pear' , 'grape' , 'banana' ]) >>> 'apple' in myset True >>> 'orange' in myset False >>> for fruit in myset: print fruit grape pear apple banana |
3.更新集合
只有可变集合(set)支持更新!
1
2
3
4
5
6
7
8
9
10
11
|
>>> myset.add( 'orange' ) #使用add增加元素 >>> myset set ([ 'orange' , 'grape' , 'pear' , 'apple' , 'banana' ]) >>> myset.remove( 'pear' ) #使用remov删除元素 >>> myset set ([ 'orange' , 'grape' , 'apple' , 'banana' ]) >>> newfruit = set (( 'coco' , 'watermelon' )) >>> myset.update(newfruit) #update使用集合更新集合 >>> myset set ([ 'coco' , 'grape' , 'apple' , 'orange' , 'watermelon' , 'banana' ]) >>> del newfruit #删除集合 |
五、集合类型操作符和内建函数,内建方法
1.标准类型操作符
成员关系判定
in, not in
集合等价/不等价
== !=
子集/超集判定(<, <=, >, >=)
1
2
3
4
|
>>> set ( 'book' ) < = set ( 'bookshop' ) True >>> set ( 'supermarket' ) > = set ( 'market' ) True |
2.集合类型操作符(用于可变集合和不可变集合)
1
2
3
4
5
6
7
8
9
10
|
>>> s = set ( 'abcde' ) >>> t = set ( 'defgh' ) >>> s | t #联合操作,或称OR操作,也就是算并集 set ([ 'a' , 'c' , 'b' , 'e' , 'd' , 'g' , 'f' , 'h' ]) >>> s & t #求交集操作,或称AND操纵 set ([ 'e' , 'd' ]) >>> s - t #求差集/相对补集 set ([ 'a' , 'c' , 'b' ]) >>> s ^ t #对称差分,类似C中亦或操作XOR set ([ 'a' , 'c' , 'b' , 'g' , 'f' , 'h' ]) |
3.集合类型操作符(用于可变集合)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
>>> s = set (( 1 , 3 , 5 , 7 )) >>> t = set (( 5 , 7 , 9 , 0 )) >>> s | = t >>> s set ([ 0 , 1 , 3 , 5 , 7 , 9 ]) >>> s & = t >>> s set ([ 0 , 9 , 5 , 7 ]) >>> s - = t >>> s set ([]) >>> s ^ = t >>> s set ([ 0 , 9 , 5 , 7 ]) |
这里很好理解,因为是可变集合,所以可以将上一部分讲的集合类型操作符以算数自反赋值的方式应用到集合上,当然,对不frozenset来说是不行的。
4.内建函数和工厂函数
len()是内建函数,可以计算集合大小,即集合中元素的个数。
set()是可变集合的工厂函数,用来生产可变集合,用法见“集合的创建和赋值”
frozenset()是不可变集合的工厂函数,用法和set()相同,见“集合的创建和赋值”
5.集合类型的内建方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#用于所有集合的方法 s.issubset(t) #如果s是t的子集,返回True s.issuperset(t) #如果s是t的超级,返回True s.union(t) #返回一个新集合(s和t的并集) s.intersection(t) #返回一个新集合(s和t的交集) s.difference(t) #返回一个新集合(s - t) s.symmetric_difference(t) #返回一个新集合(s ^ t) s.copy() #返回一个新集合,它是s的浅复制 #仅用于可变集合的方法 s.update(t) #用t中的元素更新s s.intersection_update(t) #将t中的元素并入到s中 s.difference_update(t) #s中现在是s和t的交际 s.symmetric_difference_update(t) #s中现在是(s - t) s.add(obj) #在s中添加对象obj s.remove(obj) #从s中删除对象obj,如果不存在则引发KeyError异常 s.discard(obj) #如果obj是s的元素,就从s中删除 s.pop() #删除s中任意一个对象,并返回 s.clear() #删除集合s中的所有元素 |
六、小结
至此,我们已经学完了Python所有的基本内建类型:数字,字符串,列表,元组,映射,集合。这些数据类型功能强大,使用简单,能够熟练使用它们是后续学习的关键。
参考博客:http://greenlcat.diandian.com/post/2012-10-10/40039924285
Python:映像、集合的更多相关文章
- python爬虫工具集合
python爬虫工具集合 大家一起来整理吧!强烈建议PR.这是初稿,总是有很多问题,而且考虑不全面,希望大家支持! 源文件 主要针对python3 常用库 urllib Urllib是python提供 ...
- Python序列结构--集合
集合:元素之间不允许重复 集合属于Python无序可变序列,元素之间不允许重复 集合对象的创建与删除 直接将值赋值给变量即可创建一个集合 >>> a = {3,5}>>& ...
- python 中的集合set
python中,集合(set)是一个无序排列,可哈希, 支持集合关系测试,不支持索引和切片操作,没有特定语法格式, 只能通过工厂函数创建.集合里不会出现两个相同的元素, 所以集合常用来对字符串或元组或 ...
- 【转】Python数据类型之“集合(Sets)与映射(Mapping)”
[转]Python数据类型之“集合(Sets)与映射(Mapping)” 一.集合类型(Sets) 集合对象是不同的(不可重复)hashable对象的无序集合.常见用法包括:成员关系测试.移除序列中的 ...
- Python的set集合详解
Python 还包含了一个数据类型 -- set (集合).集合是一个无序不重复元素的集.基本功能包括关系测试和消除重复元素.集合对象还支持 union(联合),intersection(交),dif ...
- python入门13 集合set
set集合与数学中的集合同一个概念,是无序不重复元素组成的. #coding:utf-8 #/usr/bin/python """ 2018-11-10 dinghanh ...
- Python中的集合类型分类和集合类型操作符解析
集合类型 数学上,把set称作由不同的元素组成的集合,集合(set)的成员通常被称作集合元素(set elements). Python把这个概念引入到它的集合类型对象里.集合对象是一组无 ...
- Python列表、集合与字典(3)
目录 一.列表 二.集合 三.字典 一.列表 1. 列表初识 列表的使用为处理特定顺序排列的数据提供了便利,列表元素可以是字母.数字或者其他信息,同时所加元素之间不存在任何关系. 在Pytho ...
- python学习之【第七篇】:Python中的集合及其所具有的方法
1.前言 python中的集合set与列表类似,它们最大的区别是集合内不允许出现重复元素,如果在定义时包含重复元素,会自动去重. 集合是无序的,集合中的元素必须是不可变类型.集合可以作为字典的key. ...
- python常用模块集合
python常用模块集合 Python自定义模块 python collections模块/系列 Python 常用模块-json/pickle序列化/反序列化 python 常用模块os系统接口 p ...
随机推荐
- [原]1856-More is better-基础并查集
思路:注意n为0的时候输出1,还有内存.这题是数据水了,要不我的Count[ ]数组,开10^5绝对会WA.离散化还没想清楚,想清楚了再更新代码.[水过代码下面是正经的AC代码,其实这道题不用离散化, ...
- WINCE设备开机灰屏问题(很怪异)
WINCE设备开机灰屏问题(很怪异) 1. 问题现象 图1 无法进入系统,虽然没有调试信息,但应该可以判断是程序跑飞了.我们这款产品用到3种显示屏(采用不同的驱动IC),可是测试发现1和2号屏 ...
- 第三篇 从EXCEL电子表格到数据库
一个靠EXCEL电子表格处理各部门业务数据的公司和一个使用一个统一的数据库存储各个部门用到的业务数据并提供大量权限不同的使用界面给用户的公司两者有什么不同呢? EXCEL电子表格是数据和操纵数据的 ...
- 谈谈 char *num="123";和char num[4]="123";的区别
最近写程序的时候发现这样一个问题 #include<iostream> #include <string.h> using namespace std; void revers ...
- serialize-and-deserialize-bst
https://leetcode.com/problems/serialize-and-deserialize-bst/ 1. 用到Java Queue接口, // LinkedList实现了Queu ...
- C#判断字符串为空的几种方法和效率判断
C#判断字符串为空的几种方法和效率判断 string定义 1.1 string str1="":会定义指针(栈),并在内存里划一块值为空的存储空间(堆),指针指向这个空间.1.2 ...
- bzoj4127
肯定是树链剖分+线段树,关键是怎么维护 绝对值和这个东西显然不能简单的合并标记 因为对于负数,加之后绝对值和是变小的 那我们考虑对负数和非负数数分别维护 下面的问题就是经过操作如果负数变成了正数怎么办 ...
- C#操作office进行Excel图表创建,保存本地,word获取
,新建C#控制台应用程序(Excel创建图表) using System; using System.Collections.Generic; using System.Linq; using Sys ...
- HDU 5371 Hotaru's problem (Manacher,回文串)
题意:给一个序列,找出1个连续子序列,将其平分成前,中,后等长的3段子序列,要求[前]和[中]是回文,[中]和[后]是回文.求3段最长为多少?由于平分的关系,所以答案应该是3的倍数. 思路:先Mana ...
- UVALive 4043 Ants 蚂蚁(二分图最佳完美匹配,KM算法)
题意: 有n个蚂蚁n棵树,蚂蚁与树要配对,在配对成功的一对之间连一条线段,要求所有线段不能相交.按顺序输出蚂蚁所匹配的树. 思路: 这个题目真是技巧啊,不能用贪心来为每个蚂蚁选择最近的树,这样很可能是 ...