基本数据类型(二)
1. 列表
列表是 python 最常用的数据类型,它是有序元素的集合,元素之间以逗号分隔,用中括号括起来,可以是任何数据类型。同时它也是一种序列,支持索引、切片、加、乘和成员检查等。
- 数组:数据类型必须一致,有序的元素序列。
- 列表:python 中没有数组的概念,列表是一种特殊的数组,不要求数据类型一致,在内存中存储方式类似于链表。
索引:即序列中元素的位置,从 0 开始
1.1 基本操作
1. 创建列表
>>> l = [] # 创建一个空列表 >>> l = [3, '2', 6]
2. 获取元素
获取元素有三种方法,分别是:
- 通过索引获取
- 列表切片获取(获得列表)
- for 循环
>>> l = [3, '2', 6] >>> l[1] # 索引 '2' >>> l[0:2] # 切片 [3, '2'] >>> for i in l: # for 循环 ... print(i) ... 3 2 6
3. 删除元素
del 语句可以删除整个列表,也可以用来删除某个元素:
>>> l = [3, '2', 6] >>> del l[1] # 删除索引为 1 的元素 >>> l [3, 6] >>> del l[0:1] # 切片删除 >>> l [6] >>> del l # 删除整个列表
4. 修改列表
列表修改,可以通过索引赋值修改,也可以通过切片修改:
>>> l = [3, '2', 6] >>> l[1] = 4 # 通过索引赋值操作 >>> l [3, 4, 6] >>> l[0:2] = [4, 5] # 切片修改 >>> l [4, 5, 6]
5. 成员运算
列表支持 in、not in 成员运算,返回布尔值:
>>> l = [10, 22, 33, 66] >>> 10 in l true >>> 22 not in l false
6. 获取列表中列表中的元素
列表支持多级索引:
>>> l = [10, 22, [33, 44], 66] >>> l[2][1] 44
7. 类型转换
通过 list()函数可以将其他数据类型转换为列表,需要注意的是 数字不能转换为列表,因为数字不是可迭代对象。
>>> list('123') ['1', '2', '3'] >>> list({'name':'rose', 'age':18}) ['name', 'age']
列表转换为字符串:
>>> l = ['abc', '123'] # 列表中只有字符串时,使用 .join()方法 >>> ''.join(l) 'abc123' >>> l = ['abc', 123] # 当列表中有数字时 >>> s = '' >>> for i in l: ... s += str(i) ... >>> print(s) abc123
8. 切片(slice)
列表是有序元素的集合,支持切片操作,slice(start,stop[,step])
有三个参数,开始结束位置以及步长。切片是对原列表的浅拷贝,不改变原列表。
>>> l = [10, 22, 33, 66] >>> l[0:2] # 包含开始位置,不包含结束位置 [10, 22] >>> l[:3] # 省略开始位置 [10, 22, 33] >>> l[2:] # 省略结束位置 [33, 66] >>> l[:] # 对原列表拷贝(副本) [10, 22, 33, 66] >>> l[:3:2] # 步长为 2 [10, 33] >>> l[::2] # 对原列表拷贝,步长为 2 [10, 33] >>> l[::-1] # 反转列表 [66, 33, 22, 10]
1.2 列表内置方法
# append(obj):在列表最后添加一个元素 >>> l = [2, 3] >>> l.append(6) >>> l [2, 3, 6] # clear():清空列表中所有元素 >>> l = [2, 3] >>> l.clear() >>> l [] # copy():浅拷贝 >>> l = [2, 3] >>> l1 = l.copy() >>> l1 [2, 3] # count(value):统计列表中某个元素的个数 >>> l = ['a', 'b', 'c', 'a'] >>> l.count('a') 2 # extend(iterable):往列表最后添加多给元素,参数必须是可迭代对象 >>> l = ['a', 'b', 'c', 'a'] >>> l.extend('12') >>> l.extend([3, 5]) >>> l ['a', 'b', 'c', 'a', '1', '2', 3, 5] # index(value,start=none,end=none):查找某个元素的位置,可指定范围,当有多个时,仅返回第一个的位置 >>> l = ['a', 'b', 'c', 'a', '1', '2', 3, 5] # 若不存在报 valueerror >>> l.index('a') 0 # insert(index,value):往列表中任意位置插入一个元素,第一个为插入位置,第二个为插入元素 >>> l = ['a', 'b'] >>> l.insert(1, 2) >>> l ['a', 2, 'b'] # pop(index=none):删除一个元素,并获得它,默认是最后一个,可以指定索引 >>> l = ['a', 'b', 'c'] >>> res = l.pop() >>> res 'c' >>> l ['a', 'b'] >>> l.pop(1) 'b' >>> l ['a'] # remove(value):删除一个元素,当有多个时,仅删除第一个 >>> l = ['a', 'b', 'c', 'a'] >>> l.remove('a') >>> l ['b', 'c', 'a'] # reverse():列表反转 >>> l = ['a', 'b', 'c', 'a'] >>> l.reverse() >>> l ['a', 'c', 'b', 'a'] # sort(func,key=none,reverse=true):对列表中的元素进行排序,func 为排序算法(默认从小到大),key 为关键字,reverse=false 表示不颠倒顺序,true 表示从大到小 >>> l = [22, 11, 33, 10] >>> l.sort() >>> l [10, 11, 22, 33] >>> l.sort(reverse=true) >>> l [33, 22, 11, 10]
2. 元组
元组是一种特殊的列表,也是一种有序元素的集合,与列表的区别:
- 列表:可以修改、增加、删除,使用中括号括起来
- 元组:一旦创建不可修改、增加、删除,使用小括号括起来
2.1 基本操作
1. 创建
一般在创建元组时,推荐在最后一个元素加一个逗号【,】
>>> temp = () >>> temp = (3,) >>> temp = (2, 3, 'ab',)
2. 获取
元组获取元素与列表一样,同样地可以通过索引、切片以及 for 循环遍历获取。其他数据类型转换为元组,使用 tuple()函数,方法与 list()一样。
>>> temp = (2, 3, 'ab') >>> temp[1] 3 >>> temp[0:2] (2, 3) >>> for i in temp: ... print(i) 2 3 ab
3. 更新
元组一旦创建,其一级元素不可被修改,但是元组里面的二级元素(如 元组中的列表中的元素)可以被修改。
>>> temp = (2, 3, ['a', 'b'], 4) >>> temp[2][0] = 'c' >>> temp (2, 3, ['c', 'b'], 4)
另外还可以类似于 str 一样,使用连接符 + 对其进行间接修改。但是需要注意的是,使用连接符修改将会产生一个新的元组(即验证了元组不可被修改)。
>>> temp = (2, 3, 4) >>> id(temp) 47622040 >>> temp = temp[:2] + (5,) + temp[2:] # 在索引为 2 的位置插入一个元素 5 >>> temp (2, 3, 5, 4) >>> id(temp) # 前后元组名相同,但 id 不同,不是一个元组 39030600
4. 删除
一般情况,元组不使用时,将会被 python 的回收机制自动删除,因此不用特意删除。
>>> temp = (2, 3, 4) >>> temp = temp[:1] + temp[2:] >>> temp (2, 4) >>> del temp # 删除整个元组
2.2 内置函数
# len(obj):获取元组长度 >>> temp = (2, 3, 4) >>> len(temp) 3 # max、min(obj):获取元组中元组最大、小值 >>> max(temp) 4 >>> min(temp) 2 # tuple():类型转换 >>> tuple('123' ... ) ('1', '2', '3') >>> tuple({'name':'rose', 'age':18}) ('name', 'age')
2.3 内置方法
# count(value):统计某个元素个数 >>> temp = (2, 3, 4, 2) >>> temp.count(2) 2 # index(value,start=none,end=none):获取某个元素位置,若不存在,报 valueerror >>> temp.index(2, 0, 3) 0
2.4 元祖拆包
元组拆包即将元组中的元素平行赋值给变量。
>>> x,y,z = (1,2,3) >>> print(x,y,z) 1 2 3 >>> infos = [(1,2,3), (4,5,6)] >>> for i in infos: ... print('%s %s %s'%i) ... 1 2 3 4 5 6
3. 字典
字典是一种可变容器模型,可以存储任意类型对象。由无序的键(key)值(value)对组成,每对之间以逗号分割,最外层以花括号包裹。
- 键:任意不可变类型(int、str、tuple 等),必须是唯一的。
- 值:任意类型
3.1 基本操作
1. 创建
>>> d1 = {} >>> d2 = {'name': 'rose', 'age': 18} >>> d3 = dict()
2. 访问
因为字典是无序的,所有只能通过 key 来访问 value:
>>> d2 = {'name': 'rose', 'age': 18} >>> d2['name'] # 这种方法,当 key 不存在是会报 keyerror 'rose' >>> d2.get('age') 18
3. 删除
del 语句可以用来删除一个元素,也可用于删除整个字典:
>>> d2 = {'name': 'rose', 'age': 18} >>> del d2['name'] # 删除 name >>> d2 {'age': 18} >>> del d2 # 删除整个字典
4. 修改
通过 key 访问到 value,对其进行赋值,便可完成修改:
>>> d2 = {'name': 'rose', 'age': 18} >>> d2['name'] = 'tom' >>> d2 {'name': 'tom', 'age': 18}
3.2 内置方法
part 1
# fromkeys(sequence[, value]):内置的类方法 @staticmethod,接收一个序列,将序列中的元素作为键,value 默认为 none,返回一个新的字典 >>> d = dict.fromkeys(['a', 'b'], 2) >>> d {'a': 2, 'b': 2} # get(key[, value]):根据 key 获取 value,即使 key 不存在也不会报错,若 key 存在可以指定返回值 >>> d2 = {'name': 'rose', 'age': 18} >>> d2.get('age') 18 >>> d2.get('gender', '没找到') '没找到' # pop(key[,default]):根据 key 删除一个元素,若 key 在字典中,将其删除并返回。否则返回默认值,如果 key 不存在,且又未指定默认值,引发 keyerror >>> d2 = {'name': 'rose', 'age': 18} >>> s = d2.pop('name') >>> s 'rose' >>> d2.pop('gender', "don't find") "don't find" >>> d2.pop('gender') # key 不存在,且又未指定默认值,引发 keyerror traceback (most recent call last): file "<stdin>", line 1, in <module> keyerror: 'gender' # popitem():从字典中随意删除一个元素,并返回 >>> d2 = {'name': 'rose', 'age': 18} >>> s = d2.popitem() >>> s ('age', 18) >>> d2 {'name': 'rose'} # setdefault(key[,default]):设置字典键值对,若存在,不设置,并获取当前 key 对应的 value。若不存在,设置 >>> d2 = {'name': 'rose', 'age': 18} >>> d2.setdefault('gender', 'male') 'male' >>> d2.setdefault('age', 19) 18 >>> d2 {'name': 'rose', 'age': 18, 'gender': 'male'} # update(**kwargs):更新字典 >>> d2 = {'name': 'rose', 'age': 18} >>> d2.update(age=20, gender='male') # 若 key 存在,在更新,若不存在则新建键值对 >>> d2 {'name': 'rose', 'age': 20, 'gender': 'male'} >>> d2.update({'a':20}) # 传入一个字典 >>> d2 {'name': 'rose', 'age': 18, 'a': 20}
part 2
# keys():返回字典的 key >>> d2 = {'name': 'rose', 'age': 18} >>> k = d2.keys() >>> k dict_keys(['name', 'age']) >>> for i in k: ... print(i) ... name age # values(): 返回字典的 value >>> v = d2.values() >>> v dict_values(['rose', 18]) >>> for i in v: ... print(i) ... rose 18 # items():返回字典的 key、value >>> for k, v in d2.items(): ... print(k, v) ... name rose age 18 # clear():清空整个字典里的元组 >>> d2 = {'name': 'rose', 'age': 18} >>> d2.clear() >>> d2 {} # copy():对字典进行浅拷贝 >>> d2 = {'name': 'rose', 'age': 18} >>> d = d2.copy() >>> d {'name': 'rose', 'age': 18}
4. 集合
由不同元素组成的无序集合,里面的元素必须是不可变的,且每个元素都是唯一的。
- 无序,不能用索引方式访问
- 只能是数字、字符串、元组等不可变数据
4.1 基本操作
1. 创建
创建一个集合有两种方法:一是直接用大括号把一堆元素括起来;另一种是使用 set()。
>>> s = {1, 2, 3} # 不能使用大括号直接创建一个空集合,那样会创建一个字典 >>> s = set('123') >>> s {'3', '1', '2'} >>> s = {1, 2, 3, 2} # 创建一个重复的集合,会自动将重复的元素过滤 >>> s {1, 2, 3}
2. 访问
因为集合中元素是无序的,所以不能通过索引访问,只能用 for 循环每个元素,或成员运算符判断元素是否在集合中。
>>> s = {'3', '1', '2'} >>> for i in s: ... print(i) ... 3 1 2 >>> '3' in s true
3. 转换类型
不能将数字和字典转换为集合。
>>> set([1,2,3]) {1, 2, 3} >>> set('123') {'3', '1', '2'}
4.2 内置方法
# add(*args, **kwargs):添加一个元素 >>> s = {1, 2, 3} >>> s.add(4) >>> s {1, 2, 3, 4} # clear():清空集合 >>> s = {1, 2, 3} >>> s.clear() >>> s set() # copy():浅拷贝 >>> s = {1, 2, 3} >>> s1 = s.copy() >>> s1 {1, 2, 3, 4} # pop():随机移除一个元素 >>> s1 = {1, 2, 3} >>> s1.pop() 1 >>> s1 {2, 3} # remove(value):删除某个指定元素,若元素不存在抛出 keyerror >>> s1 = {1, 2, 3} >>> s1.remove(2) >>> s1 {1, 3} # discard(value):与 remove()一样都是删除某个元素,但是元素不存在不会报错 >>> s1 = {1, 2, 3} >>> s1.discard(4) # difference_update(set2):更新集合,相当于 s1 = s1 - s2 >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.difference_update(s2) >>> s1 {1} # intersection_update(set2):求交集,与 intersection()不同的是它不会改变原集合,而 intersection()返回新的集合 >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.intersection(s2) {2, 3} >>> s1 {1, 2, 3} # set1.isdisjoint(set2):判断两个集合有无交集,有交集返回 false >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.isdisjoint(s2) false # s1.issubset(set2):判断 set1 是否是 set2 的子集(即 set1 <= set2) # set1.issuperset(set2):判断 set1 是否是 set2 的父集 >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.issubset(s2) false >>> s1.issuperset(s2) false # set.update(set2):给集合添加元素,参数可以是集合、字符串、列表、元组、字典等 >>> s1 = {1, 2, 3} >>> s1.update({'a':'b'}) # 字典 >>> s1 {1, 2, 3, 'a'} >>> s1.update([4, 5]) # 列表 >>> s1.update({6, 7}) # 集合 >>> s1 {1, 2, 3, 4, 5, 6, 7, 'a'} # set1.symmetric_difference_update(set2):求交叉补集,在原集合上更新,将不重复的元素添加到原集合中 >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.symmetric_difference_update(s2) >>> s1 {1, 4}
不可变集合
有时想要像元组一样不能随意添加、删除集合元素,可以使用 frozenset()函数定义一个不可变集合。
>>> s1 = frozenset({1, 2, 3}) >>> s1.add(4) traceback (most recent call last): file "<stdin>", line 1, in <module> attributeerror: 'frozenset' object has no attribute 'add'
4.3 集合关系运算
1. 交集(&)
交集即两个集合重复的部分,intersection()方法可以用来求两个集合的交集,并返回交集,不改变原集合。
set1.intersection(set2) set1 & set2
>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.intersection(s2) {2, 3} >>> s1 {1, 2, 3} >>> s1 & s2 {2, 3}
2. 并集(|)
并集即将两个集合的所有元素并在一起,重复的只出现一次,可以用作简单去重。
set1.union(set2) set1 | set2
>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.union(s2) {1, 2, 3, 4} >>> s1 | s2 {1, 2, 3, 4}
3. 差集(-)
差集即 set1 - set2
,两个集合中重复的元素去掉,仅包含第一个集合中剩余的元素,不包含第二个集合剩余的元素,不改变原集合。
set1.difference(set2) set1 - set2
>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.difference(s2) {1} >>> s1 - s2 {1} >>> s1 {1, 2, 3}
4. 交叉补集(^)
交叉补集即两个集合不重复的元素,不改变原集合。
set1.symmetric_difference(set2) set1 ^ set2
>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1.symmetric_difference(s2) {1, 4} >>> s1 {1, 2, 3} >>> s1 ^ s2 {1, 4}
5. 去重
可以利用集合对列表进行简单去重,先将其转换为集合,再转换为列表,需要注意的是,元素顺序将会改变。
>>> names = ['rose', 'lila', 'tom', 'rose'] >>> names = list(set(names)) >>> names ['lila', 'tom', 'rose']
5. 序列
序列即有序元素集合,是可迭代对象,包括字符串、列表、元组,它们之间用很多共同点:
- 都可以通过索引获取值,即是有序(索引从 0 开始)
- 可以切片
- 有共同的操作符(重复、拼接、成员关系操作符等)
enumerate()方法
enumerate(iterable)方法用于生成一个二元组(二元组即元素数量为二的元组)构成的一个可迭代对象,每个二元组由可迭代索引与对应元素组成。
>>> s = 'abc' >>> for i in enumerate(s): ... print(i) ... (0, 'a') (1, 'b') (2, 'c')
6. 练习
字典无限嵌套
cities={ '北京':{ '朝阳':['国贸','cbd','天阶','我爱我家','链接地产'], '海淀':['圆明园','苏州街','中关村','北京大学'], '昌平':['沙河','南口','小汤山',], '怀柔':['桃花','梅花','大山'], '密云':['密云a','密云b','密云c'] }, '河北':{ '石家庄':['石家庄a','石家庄b','石家庄c','石家庄d','石家庄e'], '张家口':['张家口a','张家口b','张家口c'], '承德':['承德a','承德b','承德c','承德d'] } } for i in cities['北京']: print(i) 朝阳 海淀 昌平 怀柔 密云 for i in cities['北京']['海淀']: print(i) 圆明园 苏州街 中关村 北京大学
上一篇: 使用工厂模式解耦和IoC思想