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 ...
随机推荐
- dojo 资源库
文档 :http://wenku.baidu.com/link?url=Nnek_tAjIC-Q3t3e9zHQmsh4LhU3f0ncC1QH8WD_U9-I8-fJ7mMisscFpgfuS8nU ...
- UUID的具体用法
String deleteUuid = UUID.randomUUID().toString(); java.util 类 UUID java.lang.Object java.util.UUID 所 ...
- pl/sql programming 02 创建并运行plsql代码
/* * chap 02 * ------------------------------------------------- */ create or replace function wordc ...
- Qt环境搭建(Visual Studio)
简述 经常有人问我编写Qt程序时使用什么IDE,其实这个真的很难回答(各有所长),只能说看个人爱好了,因为我两个都用,而且两个都很喜欢(比较多情吧O(∩_∩)O~)! 下面将进行Qt Creator与 ...
- file类型允许的文件格式设置问题,“选择文件”打开缓慢
1,file类型的input对于打开的选择框的属性是由以下两个属性控制的: ①multiple="multiple" :一次可以选择多个文件 ②accept="image ...
- [转] 判断html页是否滚动停止
原文链接:http://www.phpernote.com/javascript-function/754.html 最近有个项目中遇到这样一个问题: 有一个用于展示数据的带滚动条的DIV块,业务需求 ...
- UVA 11354 Bond 邦德 (RMQ,最小瓶颈MST)
题意: n个城市,m条路,每条路有个危险值,要使得从s走到t的危险值最小.回答q个询问,每个询问有s和t,要求输出从s到t最小的危险值.(5万个点,10万条边) 思路: 其实要求的是任意点对之间的最小 ...
- Android如何获取系统高度、标题栏和状态栏高度
在android应用中,有时需要计算个View的位置,导致需要计算状态栏高度,标题栏高度等信息.为以后方便,在此做个简单记录. 晒代码前先了解一下android屏幕区域的划分,如下图(该图引用自此文h ...
- Shell教程6-Shell注释
以“#”开头的行就是注释,会被解释器忽略. sh里没有多行注释,只能每一行加一个#号.只能像这样: #-------------------------------------------- # 这是 ...
- check windows return character
#ifndef _FILE_CHECK_H#define _FILE_CHECK_H#include <string.h>#include <vector> const int ...