Python数据类型之无序列数据类型
序列数据类型可进行for遍历的数据类型,同时,
无序序列数据类型,也就是说,该数据类型还不可进行索引;不可切片;不可使用连接操作符、重复操作符以及成员操作符。
以列表
和集合
为例:列表作为有序数据数列如果为其追加元素,那么,追加的元素势必在列表的最右边;而集合作为无序数列,添加的元素不一定会在集合的最右边。
>>> a = [99, 12, 1,88]
>>> a.append(0)
>>> a
[99, 12, 1, 88, 0]
>>> b = {99, 12, 1, 88}
>>> b.add(0)
>>> b
{0, 1, 99, 12, 88}
1. 集合
集合是一个无序不重复的元素序列。
创建方式:
- 使用大括号 { } 或者 set() 函数创建有元素的集合;
- 注意:
如果是创建一个空集合必须用 set() 而不是 { }
{ } 是用来创建一个空字典。
>>> s1 = {}
>>> s2 = {1,2,3}
>>> s3 = {1,2,3,'hello',(1,2,3),[1,2,3]} # 集合s3不能被创建,因为元素中有可变数据类型->列表
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> s4 = set('abracadabra')
>>> type(s1) # 空集合不可利用{}创建,s1为字典
<class 'dict'>
>>> type(s2)
<class 'set'>
>>> basket
{'orange', 'pear', 'apple', 'banana'}
>>> s4
{'b', 'd', 'r', 'c', 'a'}
1. 1 集合的内建方法 (增、删、查)
- 增
- add(),为集合增加一个元素
- update(), 一次增加多个元素
>>> s2
{1, 2, 3}
>>> s2.add(100)
>>> s2
{1, 2, 3, 100}
>>> s2.update({101, 102, 103})
>>> s2
{1, 2, 3, 100, 101, 102, 103}
- 删
- clear(),移除集合中的所有元素
- diacard(),删除集合中的指定元素,
如该元素不存在,不做任何操作
- remove(),移除指定元素,
如该元素不存在,引起KeyError异常
- pop(),随机移除元素
>>> s2
{1, 2, 3, 100, 101, 102, 103}
>>> s2.discard(101)
>>> s2
{1, 2, 3, 100, 102, 103}
>>> s2.discard(10000) # 虽然元素10000不存在,但不会出现任何异常
>>> s2.remove(1)
>>> s2
{2, 3, 100, 102, 103}
>>> s2.remove(9999) # 元素9999不存在,引发异常
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 9999
>>> item = s2.pop()
>>> item
2
>>> item = s2.pop()
>>> item
3
>>> s2.clear()
>>> s2
set()
- 查 (关于集合的运算)
- 差集,- <==> difference();difference_update()
- 交集,& <==> interserction();interserction_update()
- 对等差分,^ <==> symmetric_difference();symmetric_difference_update()
- 并集,| <==> union()
- 判断:
isdisjoin(),判断是否无交集的
issubset(),判断子集
issuperset(),判断 ”父集“,即包含关系,示例说明
>>> set1 = {1, 2, 3}
>>> set2 = {1, 2, 4}
>>> set1 & set2
{1, 2}
>>> set1.intersection(set2)
{1, 2}
>>> set1 | set2
{1, 2, 3, 4}
>>> set1.union(set2)
{1, 2, 3, 4}
>>> set1 - set2
{3}
>>> set1.difference()
{1, 2, 3}
>>> set1 ^ set2
{3, 4}
>>> set1.symmetric_difference(set2)
{3, 4}
>>> set1.isdisjoint(set2)
False
>>> set3 = {1, 2}
>>> set3.issubset(set1)
True
>>> set1.issuperset(set3)
True
>>> set1.intersection(set2)
{1, 2}
>>> set1.intersection_update(set2) # 将交集的返回结果赋值给 set1
>>> set1
{1, 2}
ps: 说明xxx_update()的意思,比如:set1.intersection_update(set2) <==> set1 = set1 & set2
,即将最后取交集的结果赋值给set1
1. 2 拓展——frozenset
frozenset即set 的不可变版本,不可进行增加、删除操作。应用场景:集合中元素不需要进行改变的,frozenset会更加安全。
>>> set1 = frozenset({1, 2, 3})
>>> set1
frozenset({1, 2, 3})
>>> set1.add(100)
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add'
>>> set1.remove(1)
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'remove'
2. 字典
字典是另一种可变容器模型,以 键:值
的形式存储数据,且可存储任意类型对象。键,一般是唯一的,且是不可变数据类型组成的,如果重复的最后的一个键:值对会替换前面的,值不需要唯一。
三种常用的字典创建方式:
>>> info = {"name":"xiaohong", "passwd":"12345"}
>>> info2 = zip(["name","passwd"], ["xiaogang", "6666"])
>>> info2 = dict(info2)
>>> info3 = dict(name="xiaohong", passwd="12345") # 比较推荐,少切换
>>> type(info)
<class 'dict'>
>>> type(info2)
<class 'dict'>
>>> type(info3)
<class 'dict'>
2. 1 字典的内建方法 (增、删、改、查)
- 增、改
- dict[new_key] = value,根据 key值;
- setdefault(),如果key值存在,不做修改;如果key值不存在,添加此key:value值;默认情况下 value 值为None;
- update(),(可批量添加key:value值) 如果key值存在,更新 value值;如果key值不存在,添加此key:value值;
>>> info
{'name': 'xiaohong', 'passwd': '12345'}
>>> info["addr"] = "beijing"
>>> info
{'name': 'xiaohong', 'passwd': '12345', 'addr': 'beijing'}
>>> info.setdefault("name", "hahahahah")
'xiaohong'
>>> info # key值存在,setdefault不做操作
{'name': 'xiaohong', 'passwd': '12345', 'addr': 'beijing'}
>>> info.setdefault("phone", "987654")
'987654'
>>> info # key值不存在,setdefault添加元素
{'name': 'xiaohong', 'passwd': '12345', 'addr': 'beijing', 'phone': '987654'}
>>> new_info = {'name': 'xiaogang', 'passwd': '6666', "qq": "22222"}
>>> info.update(new_info) # 如果key值存在,更新 value值;如果key值不存在,添加此key:value值;
>>> info
{'name': 'xiaogang', 'passwd': '6666', 'addr': 'beijing', 'phone': '987654', 'qq': '22222'}
- 删
- clear(),移除字典中所有元素
- del dic[“key”] ,根据key值进行删除,key存在则删除;key不存在,则引起KeyError异常
- pop(),弹出指定的元素,key存在则弹出;key不存在,且无设置默认值则引起KeyError异常;key不存在,设置有默认值则返回默认值
- popitem(),随机删除字典中的元素
>>> info
{'name': 'xiaogang', 'passwd': '6666', 'addr': 'beijing', 'phone': '987654', 'qq': '22222'}
>>> del info["qq"]
>>> info
{'name': 'xiaogang', 'passwd': '6666', 'addr': 'beijing', 'phone': '987654'}
>>> del info["wechat"]
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 'wechat'
>>> info.pop("phone")
'987654'
>>> info.pop("msn")
Traceback (most recent call last):
File "<input>", line 1, in <module>
KeyError: 'msn'
>>> info.pop("msn", "无此key值...")
'无此key值...'
>>> info.popitem()
('addr', 'beijing')
>>> info
{'name': 'xiaogang', 'passwd': '6666'}
>>> info.clear()
>>> info
{}
- 查
- info.keys(),查看所有 key 值
- info.values(),查看所有 value 值
- info.items(),查看所有 key: value 值
- info.get(),根据key值进行查找,key存在则返回;key不存在,默认不做任何操作,也可返回自定义的默认值
>>> info
{'name': 'xiaogang', 'passwd': '6666'}
>>> info.keys()
dict_keys(['name', 'passwd'])
>>> info.values()
dict_values(['xiaogang', '6666'])
>>> info.items()
dict_items([('name', 'xiaogang'), ('passwd', '6666')])
>>> info.get("name")
'xiaogang'
>>> info.get("addr")
>>> info.get("addr", "无此key值...")
'无此key值...'
2. 2 字典的应用
- 利用key值去重,其他去重方式可参考 004_Python字符串练习_n种方法_爱奇艺校招删除重复的字符串 demo:
# 1. 用户输入
user_str = input()
# 2. 字典的应用->利用key值去重,因为{}.fromkeys(user_str).keys()返回值是一个dict_keys对象,所以list()转换成列表数据类型
# 查看keys()方法的源代码,其说明文档为:“D.keys() -> a set-like object providing a view on D's keys”,
# 所以本质上还是应用set实现去重的,因此也具有set数据类型的无序性
str_list = list({}.fromkeys(user_str).keys())
# 3. 排序保持去重后元素位置前后的一致性
str_list.sort(key=user_str.index)
# 4. 利用 join 将列表中的元素连接为一串字符串
print("".join(str_list))
- python里面不支持switch语句,所以可利用字典实现switch 语句,demo:
grade = input("Grade:")
grade_dict = {"A":"优秀", "B":"良好", "C":"合格"}
print(grade_dict.get(grade, "无效等级"))
2. 3 拓展——默认字典defaultdict
collections.defaultdict类,本身提供了默认值的功能, 默认值可以是整形,列表,集合等。
defaultdict 是 dict 的子类。但它与 dict 最大的区别在于,dict 如果程序试图根据不存在的 key 访问 value,会引发KeyError 异常;而 defaultdict 提供default_factory 属性,该为不存在的 key 来自动生成生成默认的 value。
需求
:我们想要一个能将键 (key) 映射到多个值的字(即所谓的一键多值字典)解决方案
:
- 字典是一种关联容器,每个键都映射到一个单独的值上。如果想让键映射到多个值,需要将这些多个的值保存到容器(列表或者集合)中。
- 利用collections模块中的defaultdict类自动初始化第一个值,这样只需关注添加元素。
from collections import defaultdict
# 1. 随机生成10个1-100之间的随机数
import random
nums = []
for count in range(10):
nums.append(random.randint(1, 100))
# 2. 把list中大于66的元素和小于66的元素分类存储
sort_nums_dict = defaultdict(list) # 创建一个默认字典, 默认的value为空列表[]
for num in nums:
if num > 66:
# 只需关注添加元素。
sort_nums_dict['大于66的元素'].append(num)
else:
sort_nums_dict['小于66的元素'].append(num)
print(sort_nums_dict)