零基础入门学Python系列内容的学习目录 → \rightarrow →零基础入门学Python系列内容汇总。
需要学习的基础知识有:字典、集合等。
1. 字典 字典是另一种可变容器模型,且可存储任意类型的对象。字典的每个键值对用冒号 :
分割,每个对之间用逗号(,
)分割,整个字典包括在花括号 {}
中,格式如下所示:
d = {key1 : value1, key2 : value2, key3 : value3 }
字典是Python中唯一的映射类型。映射是指两个元素集之间元素相互“对应”的关系,如图1所示。
映射类型区别于序列类型,序列类型以数组的形式存储,通过索引的方式来获取相应位置的值,一般索引值与对应位置存储的数据是毫无关系的。
example1:>>>upper = [“A”, “B”, “C”]
>>>lower = [“a”, “b”, “c”]
>>>print(“A的小写为:”, lower[upper.index(“A”)])
A的小写为: a
列表upper
、lower
的索引和相对的值是没有任何关系的,唯一有联系的是两个列表间索引号相同的元素有大小写的关系,所以我们通过upper.index("A")
间接的实现通过大写字母查找对应的小写字母的功能。但是这种方法实现起来有点别扭,所以需要有字典这种映射类型的出现。
1.1 创建和访问字典
字典的使用非常简单,它由自己的标志性符号——大括号({ }
)定义。字典由多个键及其对应的值共同构成,每一对键值组合称为项。字典中的键必须是唯一的,但值则不必;值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
example1:>>>dict1 = {“Name”:“Bob”, “Age”:7, “Class”:“First”}
>>>dict1
{‘Name’: ‘Bob’, ‘Age’: 7, ‘Class’: ‘First’}
>>>print(“学生的姓名为:”, dict1[‘Name’])
学生的姓名为: Bob
在上面例子中,“Name”、“Age”、"Class"就是键,“Bob”、7、"First"就是对应的值。
要声明一个空字典,直接用个大括号即可:
example2:>>>empty = { }
>>>empty
{ }
>>>type(empty)
<class ‘dict’>
我们也可以用 dict() 来创建字典:
example3:>>>dict1 = dict(((‘F’, 70), (‘i’, 105), (‘s’, 115), (‘h’, 104), (‘C’, 67)))
>>>dict1
{‘F’: 70, ‘i’: 105, ‘s’: 115, ‘h’: 104, ‘C’: 67}
上面的例子中之所以那么多括号,是因为dict()函数的参数可以是一个序列(但不能是多个),所以要打包成一个元组序列(列表也可以)。如果嫌上面的做法太麻烦,还可以通过提供具有映射关系的参数来创建字典:
example4:>>>dict1 = dict(F=70, i=105, s=115, h=104, C=67)
>>>dict1
{‘F’: 70, ‘i’: 105, ‘s’: 115, ‘h’: 104, ‘C’: 67}
这里要注意的是键的位置不能加上字符串的引号,否则会报错:
example5:>>>dict1 = dict(‘F’=70, ‘i’=105, ‘s’=115, ‘h’=104, ‘C’=67)
SyntaxError: keyword can’t be an expression
还有一种创建方法是直接给字典的键赋值,如果键存在,则改写键对应的值;如果不存在,则创建一个新的键并赋值:
example6:>>>dict1
{‘F’: 70, ‘i’: 105, ‘s’: 115, ‘h’: 104, ‘C’: 67}
>>>dict1[ ‘x’ ]=88
>>>dict1
{‘F’: 70, ‘i’: 105, ‘s’: 115, ‘h’: 104, ‘C’: 67, ‘x’: 88}
>>>dict1[ ‘x’ ]=120
>>>dict1
{‘F’: 70, ‘i’: 105, ‘s’: 115, ‘h’: 104, ‘C’: 67, ‘x’: 120}
下面列举五种创建同样的字典的方法:
>>>a = dict(one = 1, two = 2, three = 3)
>>>b = {‘one’ : 1, ‘two’ : 2, ‘three’ :3}
>>>c = dict(zip([‘one’, ‘two’, ‘three’], [1, 2, 3]))
>>>d = dict([(‘two’, 2), (‘one’, 1), (‘three’, 3)])
>>>e = dict({‘three’ : 3, ‘one’ : 1, ‘two’ : 2})
>>>a == b == c == d == e
True
1.2 各种内置方法
字典是Python中唯一的映射类型,字典不是序列。如果序列中试图为一个不存在的位置赋值时,会报错;但是如果是在字典中,会自动创建相应的键并添加对应的值进去。
-
1. fromkeys()
fromkeys()方法用于创建并返回一个新的字典,它有两个参数:第一个参数是字典的键;第二个参数是可选的,是传入健对应的值,如果不提供,则默认是None。
example1:>>>dict1 = { }
>>>dict1.fromkeys((1, 2, 3))
{1: None, 2: None, 3: None}
>>>dict2 = { }
>>>dict2.fromkeys((1, 2, 3), “Number”)
{1: ‘Number’, 2: ‘Number’, 3: ‘Number’}
>>>dict3 = { }
>>>dict3.fromkeys((1, 2, 3), (“one”, “two”, “three”))
{1: (‘one’, ‘two’, ‘three’), 2: (‘one’, ‘two’, ‘three’), 3: (‘one’, ‘two’, ‘three’)}
在dict3.fromkeys((1, 2, 3), ("one", "two", "three"))
的结果中fromkeys()方法并不会将值”one”
、“two”
和”three”
分别赋给键1
、2
和3
,因为fromkeys()把("one”, "two", "three")
当成一个值了。 -
2. keys()、values()和 items()
访问字典的方法有keys()、values()和items()。
keys()用于返回字典中的健,values()用于返回字典中所有的值,items()用于返回字典中所有的健值对(也就是项)。
example2:>>>dict1 = { }
>>>dict1 = dict1.fromkeys(range(3), “赞”)
>>>dict1.keys()
dict_keys([0, 1, 2])
>>>dict1.values()
dict_values([‘赞’, ‘赞’, ‘赞’])
>>>dict1.items()
dict_items([(0, ‘赞’), (1, ‘赞’), (2, ‘赞’)])
字典可以很大,有时候我们并不知道提供的项是否在字典中存在,如果不存在,Python就会报错:
>>>print(dict1[3])
Traceback (most recent call last):
File “<pyshell#43>”, line 1, in < module >
print(dict1[3])
KeyError: 3
对于代码调试阶段,报错让程序员及时发现程序存在的问题并进行修改。但是如果程序面向用户了,那么经常报错的程序肯定会被用户所遗弃。 -
3. get()
get()方法提供了更宽松的方式去访问字典项,当键不存在的时候,get()方法并不会报错,只是默默地返回了一个None,表示什么都没找到。
example3:>>>dict1 = { }
>>>dict1 = dict1.fromkeys(range(3), “赞”)
>>>dict1.get(2)
‘赞’
>>>dict1.get(3)
>>>
如果希望找不到数据时返回指定的值,那么可以在第二个参数设置对应的默认返回值:
>>>dict1.get(3,“没有”)
‘没有’
如果不知道一个键是否在字典中,那么可以使用成员资格操作符(in 或 not in)来判断:
>>>2 in dict1
True
>>>3 in dict1
False
在字典中检查键的成员资格比序列更高效,当数据规模相当大的时候,两者的差距会很明显,因为字典是采用哈希的方法一对一找到成员,而序列则是采取迭代的方式逐个比对。最后要注意的一点是,字典里查找的是键而不是值,但是在序列中查找的是元素的值而不是元素的索引。
如果需要清空一个字典,则使用clear() 方法:
>>> dict1
{0: ‘赞’, 1: ‘赞’, 2: ‘赞’}
>>>dict1.clear()
>>> dict1
{ }
有的人可能会使用将变量名赋值为一个空字典的方法来清空字典,这样做存在一定的弊端:
example4:>>>a ={“姓名”:“小明”}
>>>b = a
>>>b
{‘姓名’: ‘小明’}
>>>a = { }
>>>a
{ }
>>>b
{‘姓名’: ‘小明’}
从上面的例子中可以看出,a
、b
指向同一个字典,我们试图通过将a
重新指向一个空字典来达到清空的效果时,却发现原来的字典并没有被真正清空,只是a
指向了一个新的空字典而已。所以这种做法在一定条件下会留下安全隐患(例如,账户的数据和密码等资料有可能会被窃取)。
推荐的做法是使用clear()方法:
example5:>>>a ={“姓名”:“小明”}
>>>b = a
>>>b
{‘姓名’: ‘小明’}
>>>a.clear()
>>>a
{ }
>>>b
{ } -
4. copy()
copy()方法是复制字典:
example6:>>>a ={1:“one”, 2:“two”, 3:“three”}
>>>b = a.copy()
>>>id(a)
1480906060424
>>>id(b)
1480906060352
>>>a[1] = “four”
>>>a
{1: ‘four’, 2: ‘two’, 3: ‘three’}
>>>b
{1: ‘one’, 2: ‘two’, 3: ‘three’}
上面的例子中,id() 函数用于获取对象的内存地址。 -
5. pop()和 popitem()
pop()是给定键弹出对应的值,而popitem()是弹出一个项:
example7:>>>a ={1:“one”, 2:“two”, 3:“three”, 4:“four”}
>>>a.pop(2)
‘two’
>>>a
{1: ‘one’, 3: ‘three’, 4: ‘four’}
>>>a.popitem()
(4, ‘four’)
>>>a
{1: ‘one’, 3: ‘three’}
setdefault() 方法和 get()方法有点相似,但是setdefault()在字典中找不到相应的键时会自动添加:
example8:>>>a ={1:“one”, 2:“two”, 3:“three”, 4:“four”}
>>>a.setdefault(3)
‘three’
>>>a.setdefault(5)
>>>a
{1: ‘one’, 2: ‘two’, 3: ‘three’, 4: ‘four’, 5: None} -
6. update()
update()方法可以用来更新字典:
example9:>>>pets={“米奇”:“老鼠”, “汤姆”:“猫”, “小白”:“猪”}
>>>pets.update(小白 = “狗”)
>>>pets
{‘米奇’: ‘老鼠’, ‘汤姆’: ‘猫’, ‘小白’: ‘狗’}
之前我们学习收集参数的时候说过Python还有另一种收集方式,就是用两个星号(**
)表示,两个星号的收集参数表示为将参数们打包成字典的形式。所以收集参数其实有两种打包形式:一是以元组的形式打包,另一种则是以字典的形式打包:
example10:>>>def test(** params):
print(“有%d个参数”% len(params))
print(“它们分别是:”, params)
>>> test(a=1, b=2, c=3, d=4, e=5)
有5个参数
它们分别是: {‘a’: 1, ‘b’: 2, ‘c’: 3, ‘d’: 4, ‘e’: 5}
当参数带两个星号(**
)时,传递给函数的任意个key=value
实参会被打包进一个字典中,有打包就有解包:
>>>a = {“one”:1, “two”:2, “three”:3}
>>>test(** a)
有3个参数
它们分别是: {‘one’: 1, ‘two’: 2, ‘three’: 3}
关于集合:1. 集合是一个可变容器;
2. 集合内的数据对象都是唯一的(不能重复);
3. 集合是无序的存储结构,集合内的数据没有先后关系;
4. 集合是可迭代对象;
5. 集合相当于是只有键没有值的字典(键就是集合中的数据);
6. 集合内的元素是不可变的。
2.1 创建集合
创建集合有两种方法:一种是直接把一堆元素用大括号({})括起来;另一种是用set()。
example1:>>>set1 = {“小明”, “小红”, “小丽”}
>>>set2 = set([“小明”, “小红”, “小丽”])
>>>set1 == set2
True
去除列表[1, 2, 3, 4, 5, 5, 3, 1, 0]中的重复元素:
example2:>>>list1 = [1, 2, 3, 4, 5, 5, 3, 1, 0]
>>>list1 = list(set(list1))
>>>list1
[0, 1, 2, 3, 4, 5]
由于set()创造的集合内部是无序的,所以再调用list()将无序的集合转换成列表就不能保证原来的列表的顺序了。如果关注列表中元素的前后顺序问题,使用set()这个函数时就要注意了。
2.2 访问集合
由于集合中的元素是无序的,所以并不能像列表那样用下标来进行访问,但是可以使用迭代把集合中的数据一个个读取出来:
example1:>>>set1 = {1, 2, 3, 4, 5, 4, 3, 2, 1, 0}
>>>for each in set1:
print(each, end = ’ ')
0 1 2 3 4 5
当然也可以使用in
和not in
判断一个元素是否在集合中已经存在:
>>>0 in set1
True
>>>‘oo’ in set1
False
>>>‘xx’ not in set1
True
使用add() 方法可以为集合添加元素,使用remove() 方法可以删除集合中已知的元素:
>>>set1.add(6)
>>>set1
{0, 1, 2, 3, 4, 5, 6}
>>>set1.remove(5)
>>>set1
{0, 1, 2, 3, 4, 6}
2.3 不可变集合
使用frozenset() 函数可以定义不可变集合,即像元组一样不能随意增加或删除集合中的元素。
example1:>>>set1 = frozenset({1, 2, 3, 4, 5})
>>>set1.add(6)
Traceback (most recent call last):
File “<pyshell#26>”, line 1, in < module >
set1.add(6)
AttributeError: ‘frozenset’ object has no attribute ‘add’