Cris 的Python日记(五):Python 数据结构之元祖,字典和集合

版权声明:转载请注明出处~ 摸摸博主狗头 https://blog.csdn.net/cris_zz/article/details/83277356

0. 序

蜉恋风,奈何生之短。风恋蜉,奈何死无期。阴阳从此两相隔,极似人间爱恨情仇,故曰 谓风。

摘自·网易云音乐《谓风》·热评

1. range

# range()是一个专门用来生成自然数序列的函数
# 该函数需要三个参数:1.起始位置(可以省略,默认为0);2.终止位置(不能省略);3.步长(可以省略,默认为1)
# 和切片操作类似,也是留头不留尾

r = range(5)
print(r)    # range(0, 5)
print(list(r))  # [0, 1, 2, 3, 4]

r = range(2, 10, 2)
print(list(r))  # [2, 4, 6, 8]
r = range(10, 2, -1)  # [10, 9, 8, 7, 6, 5, 4, 3]
print(list(r))

# 用处:主要是用作for 循环的指定范围
for i in range(10):
    print(i)    # 0~9

for s in "string":
    print(s)

2. 元祖

# 元祖(tuple)和列表(list)基本一致,其实就是不可变的列表
# 如果希望数据不可变,那么使用元祖即可(实际开发使用较少)

# 创建元祖
names = ()
print(names, type(names))    # () <class 'tuple'>
names = ('james', 'cris', 'curry')
print(names)    # ('james', 'cris', 'curry')
print(names[2])  # curry

# 元祖是不可变序列,即不能为元祖中的元素重新赋值;也不能新增或删除元素
# names[1] = 'simida' # 报错

# 创建非空元祖可以省略括号,如下:
names = '詹姆斯', '科比'
print(names, type(names))    # ('詹姆斯', '科比') <class 'tuple'>
# 如果元祖只有一个元素,如果不使用括号那么该元素后面需要添加一个,来确定是元祖数据类型
# names = '雷奥',
names = ('cris')
print(names, type(names))   # cris <class 'str'>

# 元祖的解包(解构):就是将元祖中的每个值都赋值给一个变量
names = 10, 11, 12, 13
a, b, c, d = names
print(a, b, c, d)  # 10 11 12 13

# 在对元祖进行解包,变量的数量需要和元祖中的元素的个数一致
# 如果只需要取前几个元素的值,可以使用 * 来代替后面的所有元素成一个列表(但是不能同时写多个*)
a, b, *c = names
print(a, b, c)    # 10 11 [12, 13]

a, *b, c = names
print(a, b, c)       # 10 [11, 12] 13

# 利用元祖的解包来进行变量值的交换
a = 100
b = 200
a, b = b, a
print(a, b)  # 200 100

3. 可变对象

# 可变对象:对象的值可以被改变
# 对象三要素:id/type/value
# 可变对象的典型例子就是列表;不可变对象的典型例子就是元祖
# 关于变量的赋值和通过变量修改对象的值需要搞清楚这两者的区别!

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True  == 比较值
print(a is b)   # False  is 和 is not 比较内存地址
print(a is not b)   # True

4. 映射和字典

# 字典属于一种新的数据结构,叫做映射(mapping),和列表的作用类似,都是存储对象的
# 列表存储对象的性能很好,并且根据索引查询的性能也很好,但是如果不知道具体的索引,那么查询的性能就很差了(需要挨个遍历才能查询到指定的元素)
# 如果使用字典,就可以很块的根据要求查询到指定的元素(类似于java 的map)

# 字典基础:字典中可以保存多个对象,每个对象有一个唯一的key,而对象就是这个key 对应的value
# 所以字典也称之为键值对,同时字典中的每个键值对都称之为一个项(item)

# 语法:{key:value,key:value...}
d = {1: 'cris', 2: 'james', 3: 'curry'}
print(d, type(d))    # {1: 'cris', 2: 'james', 3: 'curry'} <class 'dict'>

# 字典的value 可以是任何值,但是key 必须是任意的不可变对象(int,str,bool,tuple...)
# 字典的键是不能重复的,如果出现重复的,否则后面会替换掉前面的。
# 推荐字典的键为 str 类型
# 字典的取值都是根据value 来获取的
print(d[1])  # cris

5. 字典的常用方法

# 创建字典:使用{key:value,...}
# 或者使用 dict()函数

# 1. 使用dict(arg1=value,...)函数的方式,传入的参数名就是key,值就是value,并且参数名默认数据类型就是str
d = dict(name='cris', age=12)
print(d, type(d))   # {'name': 'cris', 'age': 12} <class 'dict'>

# 2. 也可以将包含双值子序列的序列转换为字典
# 双值序列:(1,2),['cris','james'],'ab'
# 子序列:序列中的元素仍然是序列,那个这个元素就可以称之为子序列
d = dict([['name', 'james'], ('age', 23)])
print(d, type(d))    # {'name': 'james', 'age': 23} <class 'dict'>

# len()函数可以获取字典中键值对的个数
print(len(d))   # 2

# in 和 not in:in 用于检查字典是否包含指定的键,not in 用于检查字典是否不包含指定的键
print('name' in d)  # True
print('sex' in d)   # False

# 获取字典的值,根据键来获取value
print(d['age'])  # 23
n = 'name'
print(d[n])  # james

# 通过[key] 获取value,如果key不存在,那么抛出 KeyError 异常
# 如果通过get()方法,如果key 不存在,不会报错,直接返回None
print(d.get('name'))    # james
print(d.get('hello'))   # None 不会报错

# get(key,defaultValue)
print(d.get('sex', '男'))  # 可以传入默认值,如果key 不存在,那么返回默认值

# 修改字典,如果key 存在就覆盖,不存在就添加
d['name'] = '詹姆斯'
print(d['name'])    # 詹姆斯

# setdefault(key,defaultValue),如果key 存在,那么直接返回对应的value
# 如果不存在,则向字典添加这个key,并返回默认的value
print(d.setdefault('name', 'zhang3'))    # 詹姆斯
print(d.setdefault('sex', '人妖'))  # 人妖
print(d)  # {'name': '詹姆斯', 'age': 23, 'sex': '人妖'}

# update([other]):使用other 字典来更新原字典,如果有重复的key,则替换,没有就添加
d.update({'name': 'simida', 'address': '洛杉矶'})
print(d)    # {'name': 'simida', 'age': 23, 'sex': '人妖', 'address': '洛杉矶'}

# del删除字典中的键值对,key 不存在抛出异常
del d['address']
print(d)    # {'name': 'simida', 'age': 23, 'sex': '人妖'}

# popitem():随机删除字典中的键值对,一般都是删除最后一个,返回删除的键值对(元祖数据类型),如果字典是空的,抛出异常
print(d.popitem())  # ('sex', '人妖')

# pop(key):根据key 删除字典中的项,返回被删除的项中的value,key 不存在就报错
# 加上默认值,如果key 不存在就返回默认值
print(d.pop('age'))  # 23
print(d.pop('abc', '这是默认值'))  # 这是默认值

# clear()清空字典
d.clear()
print(d)    # {}

# copy():浅复制,复制后的新对象和原对象独立,但是只会简单的复制对象内部的值
# 如果对象内部的值也是可变数据类型,那么这个值不会被复制,而是拷贝该值的地址
a = {'name': 'james', 'age': 12}
b = a.copy()
print(id(a) == id(b))   # False

a = {1: {'name': 'james', 'age': 22}}
b = a.copy()
b[1]['name'] = 'curry'
# {1: {'name': 'curry', 'age': 22}} {1: {'name': 'curry', 'age': 22}}
print(a, b)

# 字典的遍历:keys():返回的是字典的所有key,以序列形式显示
a = {'name': 'james', 'age': 12}
print(a.keys())  # dict_keys(['name', 'age'])
for key in a.keys():
    print(a[key])

# values():返回的是字典的所有键值对的value,以序列形式显示
print(a.values())   # dict_values(['james', 12])
for value in a.values():
    print(value)

# items():返回字典所有的项,以序列形式显示,每个元素都是一个双值子序列
# 每个双值子序列的元素就是每个项的键和值
for k, v in a.items():
    # k= name value= james
    # k= age value= 12
    print('k=', k, 'value=', v)

6. 集合

# 集合(set)和列表非常类似
# 1. 但是集合只能存储不可变数据类型(因为需要根据对象的hash值来存储)
# 2. 集合中存储的元素唯一且无序(和插入顺序无关)

# 集合的创建:使用{}或者set()
s = {1, 23, 3, 23}
print(s)    # {1,3,23}
# 注意:使用{}表示创建的是一个空字典
s = set()
print(s, type(s))    # set() <class 'set'>

# 可以通过set()将序列和字典转化为集合,可以用于去重
s = set([1, 2, 3, 2, 1, 5])
print(s)    # {1, 2, 3, 5}

# 将字典转换为集合时,只会包含字典中的键
s = set({1: 'cris', 2: 'james', 3: 'curry'})
print(s)    # {1, 2, 3}

# 集合没有办法通过索引去操作元素,类似java 的set,但是可以通过list()转换

# 可以使用 in 和 not in 来检查元素
# 可以使用len()计算集合中元素个数
# 使用add()向集合中添加元素,没有返回值
s.add(29)

# update():可以传递序列,集合,字典(只会获取字典所有的key)
s.update({3, 1, 'hello'})
print(s)    # {1, 2, 3, 'hello', 29}
s.update([1, 2, 4])
print(s)    # {1, 2, 3, 4, 'hello', 29}
s.update({1: 'cris', 11: 'james'})
print(s)    # {1, 2, 3, 4, 11, 'hello', 29}

# pop:随机删除集合中的元素,有返回值
s.pop()
s.pop()
print(s)    # {3, 'hello', 29}

# remove:删除集合中的指定元素,没有返回值
s.remove(29)
print(s)

# clear()清空
# copy()浅复制

# 集合的运算
s1 = {1, 2, 3, 4}
s2 = {2, 3, 5, 6}
# & 交集运算
print(s1 & s2)  # {2,3}
# | 并集运算
print(s1 | s2)  # {1,2,3,4,5,6}
# - 差集运算
print(s1 - s2)  # {1,4}
print(s2 - s1)  # {5,6}
# ^ 异或集:获取两个集合不相交的部分
print(s1 ^ s2)  # {1,4,5,6}
# <= 检查一个集合是否是另一个集合的子集:子集就是该集合的每个元素都在另一个集合中出现
print({1, 2} <= {1, 2})  # True
# < 检查一个集合是否是另一个集合的真子集:超集不仅含有子集所有的元素,还含有子集没有的元素
print({1, 2} < {1, 2})    # False
# >= 和 > 同上

7. 脑图

mark

猜你喜欢

转载自blog.csdn.net/cris_zz/article/details/83277356