python基础三(数据类型)
一 引子
1 什么是数据?
x=10,10是我们要存储的数据
2 为何数据要分不同的类型
数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示
3 数据类型
数字(整形,长整形,浮点型,复数)
字符串
字节串:在介绍字符编码时介绍字节bytes类型
列表
元组
字典
集合
4 按照以下几个点展开数据类型的学习
#======================================基本使用====================================== #1、用途 #2、定义方式 #3、常用操作+内置的方法 #======================================该类型总结==================================== #存一个值or存多个值 #有序or无序 #可变or不可变(1、可变:值变,id不变。可变==不可hash 2、不可变:值变,id就变。不可变==可hash)
二 数字
整型与浮点型
#整型int 作用:年纪,等级,身份证号,qq号等整型数字相关 定义: age=10 #本质age=int(10) #浮点型float 作用:薪资,身高,体重,体质参数等浮点数相关 salary=3000.3 #本质salary=float(3000.3) #二进制,十进制,八进制,十六进制
其他数字类型(了解)
#长整形(了解) 在python2中(python3中没有长整形的概念): >>> num=2L >>> type(num) <type 'long'> #复数(了解,推荐视频:https://www.bilibili.com/video/av26786159) >>> x=1-2j >>> x.real 1.0 >>> x.imag -2.0
三 字符串
#作用:名字,性别,国籍,地址等描述信息 #定义:在单引号\双引号\三引号内,由一串字符组成 name='egon' #优先掌握的操作: #1、按索引取值(正向取+反向取) :只能取 #2、切片(顾头不顾尾,步长) #3、长度len #4、成员运算in和not in #5、移除空白strip #6、切分split #7、循环
需要掌握的操作
#1、strip,lstrip,rstrip #2、lower,upper #3、startswith,endswith #4、format的三种玩法 #5、split,rsplit #6、join #7、replace #8、isdigit
# strip 默认移除空格 name = '*egon**' print(name.strip('*')) # 移除字符串两边的* egon print(name.lstrip('*')) # 移除字符串左边的* egon** print(name.rstrip('*')) # 移除字符串右边的* *egon # lower,upper 字母小写和大写 name = 'egon' print(name.lower()) # 字符串字母小写 egon print(name.upper()) # 字符串字母大写 EGON # startswith,endswith 字符串判断是否以什么开头和结尾,返回结果布尔类型 name = 'alex_SB' print(name.endswith('SB')) # True print(name.startswith('alex')) # True # format的三种玩法 res = '{} {} {}'.format('egon', 18, 'male') res1 = '{1} {0} {1}'.format('egon', 18, 'male') res2 = '{name} {age} {sex}'.format(sex='male', name='egon', age=18) print(res) print(res1) print(res2) # split 以什么为切片,返回结果列表 name = 'root:x:0:0::/root:/bin/bash' print(name.split(':')) # 默认分隔符为空格 ['root', 'x', '0', '0', '', '/root', '/bin/bash'] name = 'C:/a/b/c/d.txt' # 只想拿到顶级目录 print(name.split('/', 1)) # ['C:', 'a/b/c/d.txt'] print(name.split('/', 2)) # ['C:', 'a', 'b/c/d.txt'] name = 'a|b|c' print(name.rsplit('|', 1)) # 从右开始切分 ['a|b', 'c'] # join tag = ' ' print(tag.join(['egon', 'say', 'hello', 'world'])) # 可迭代对象必须都是字符串 egon say hello world # replace 替代 name = 'alex say :i have one tesla,my name is alex' print(name.replace('alex', 'SB', 1)) # SB say :i have one tesla,my name is alex print(name.replace('alex', 'SB', 3)) # SB say :i have one tesla,my name is SB # isdigit:可以判断bytes和unicode类型,是最常用的用于于判断字符是否为"数字"的方法 age = input('>>: ') print(age.isdigit())
其他操作(了解即可)
#1、find,rfind,index,rindex,count #2、center,ljust,rjust,zfill #3、expandtabs #4、captalize,swapcase,title #5、is数字系列 #6、is其他
# find,rfind,index,rindex,count name = 'egon say hello' print(name.find('o', 1, 3)) # 顾头不顾尾,找不到则返回-1不会报错,找到了则显示索引 # print(name.index('e',2,4)) #同上,但是找不到会报错 print(name.count('e', 1, 3)) # 顾头不顾尾,如果不指定范围则查找所有
# center,ljust,rjust,zfill name = 'egon' print(name.center(30, '-')) # -------------egon------------- print(name.ljust(30, '*')) # egon************************** print(name.rjust(30, '*')) # **************************egon print(name.zfill(50)) # 用0填充 # 0000000000000000000000000000000000000000000000egon # expandtabs name = 'egon\thello' print(name) # egon hello print(name.expandtabs(1)) # egon hello # captalize,swapcase,title name = 'egon' print(name.capitalize()) # 首字母大写 Egon print(name.swapcase()) # 大小写翻转 EGON msg = 'egon say hi' print(msg.title()) # 每个单词的首字母大写 Egon Say Hi # is数字系列 # 在python3中 num1 = b'4' # bytes num2 = u'4' # unicode,python3中无需加u就是unicode num3 = '四' # 中文数字 num4 = 'Ⅳ' # 罗马数字 # isdigt:bytes,unicode print(num1.isdigit()) # True print(num2.isdigit()) # True print(num3.isdigit()) # False print(num4.isdigit()) # False # isdecimal:uncicode # bytes类型无isdecimal方法 print(num2.isdecimal()) # True print(num3.isdecimal()) # False print(num4.isdecimal()) # False # isnumberic:unicode,中文数字,罗马数字 # bytes类型无isnumberic方法 print(num2.isnumeric()) # True print(num3.isnumeric()) # True print(num4.isnumeric()) # True # 三者不能判断浮点数 num5 = '4.3' print(num5.isdigit()) # False print(num5.isdecimal()) # False print(num5.isnumeric()) # False ''' 总结: 最常用的是isdigit,可以判断bytes和unicode类型,这也是最常见的数字应用场景 如果要判断中文数字或罗马数字,则需要用到isnumeric ''' # is其他 print('===>') name = 'egon123' print(name.isalnum()) # 字符串由字母或数字组成 True print(name.isalpha()) # 字符串只由字母组成 False print(name.isidentifier()) # True print(name.islower()) # True print(name.isupper()) # False print(name.isspace()) # False print(name.istitle()) # False
练习
name = " aleX" # 1) 移除 name 变量对应的值两边的空格,并输出处理结果 print(name.strip()) # 2) 判断 name 变量对应的值是否以 "al" 开头,并输出结果 print(name.startswith('al')) # 3) 判断 name 变量对应的值是否以 "X" 结尾,并输出结果 print(name.endswith('X')) # 4) 将 name 变量对应的值中的 “l” 替换为 “p”,并输出结果 print(name.replace('l', 'p')) # 5) 将 name 变量对应的值根据 “l” 分割,并输出结果。 print(name.split('l')) # 6) 将 name 变量对应的值变大写,并输出结果 print(name.upper()) # 7) 将 name 变量对应的值变小写,并输出结果 print(name.lower()) # 8) 请输出 name 变量对应的值的第 2 个字符? print(name[1]) # 9) 请输出 name 变量对应的值的前 3 个字符? print(name[:3]) # 10) 请输出 name 变量对应的值的后 2 个字符? print(name[-2:]) # 11) 请输出 name 变量对应的值中 “e” 所在索引位置? print(name.find('e')) # 12) 获取子序列,去掉最后一个字符。如: oldboy 则获取 oldbo。 a=name[:-1] print(a)
四 列表
# 基本数据类型
# list
1、作用:按位置存放多个值
2、定义:在[]内,用逗号分隔开多个任意数据类型的值
# l1 = [1,'a',[1,2]] # 本质:l1 = list([1,'a',[1,2]])
3、类型转换
# 但凡能被for循环遍历的数据类型都可以传给list()转换成列表类型,list()会跟for循环一样遍历出数据类型中包含的每一个元素然后放到列表中 # >>> list('wdad') # 结果:['w', 'd', 'a', 'd'] # >>> list([1,2,3]) # 结果:[1, 2, 3] # >>> list({"name":"jason","age":18}) #结果:['name', 'age'] # >>> list((1,2,3)) # 结果:[1, 2, 3] # >>> list({1,2,3,4}) # 结果:[1, 2, 3, 4]
4、内置方法
# 1.按索引存取值(正向存取+反向存取):即可存也可以取 # 1.1 正向取(从左往右) >>> my_friends=['tony','jason','tom',4,5] >>> my_friends[0] tony # 1.2 反向取(负号表示从右往左) >>> my_friends[-1] 5 # 1.3 对于list来说,既可以按照索引取值,又可以按照索引修改指定位置的值,但如果索引不存在则报错 >>> my_friends = ['tony','jack','jason',4,5] >>> my_friends[1] = 'martthow' >>> my_friends ['tony', 'martthow', 'jason', 4, 5] # 2.切片(顾头不顾尾,步长) # 2.1 顾头不顾尾:取出索引为0到3的元素 >>> my_friends[0:4] ['tony', 'jason', 'tom', 4] # 2.2 步长:0:4:2,第三个参数2代表步长,会从0开始,每次累加一个2即可,所以会取出索引0、2的元素 >>> my_friends[0:4:2] ['tony', 'tom'] # 2.3 my_friends[:] #切片等同于拷贝行为,而且相当于浅拷贝。 # 2.4 my_friends[::-1] #整个列表取反,倒过来。 # 3.长度 >>> len(my_friends) 5 # 4.成员运算in和not in >>> 'tony' in my_friends True >>> 'xxx' not in my_friends True # 5.添加 # 5.1 append()列表尾部追加元素 >>> l1 = ['a','b.txt','c'] >>> l1.append('d') >>> l1 ['a', 'b.txt', 'c', 'd'] # 5.2 extend()一次性在列表尾部添加多个元素(拼接作用) >>> l1.extend(['a','b.txt','c']) >>> l1 ['a', 'b.txt', 'c', 'd', 'a', 'b.txt', 'c'] # 5.3 insert()在指定位置插入元素 >>> l1.insert(0,"first") # 0表示按索引位置插值 >>> l1 ['first', 'a', 'b.txt', 'c', 'alisa', 'a', 'b.txt', 'c'] # 6.删除 # 6.1 del :通用的删除方法,只是单纯的删除、没有返回值。 >>> l = [11,22,33,44] >>> del l[2] # 删除索引为2的元素,不支持赋值语法 >>> l [11,22,44] # 6.2 pop()默认删除列表最后一个元素,并将删除的值返回,括号内可以通过加索引值来指定删除元素 >>> l = [11,22,33,22,44] >>> res=l.pop() >>> res 44 >>> res=l.pop(1) >>> res 22 # 6.3 remove()括号内指名道姓表示要删除哪个元素,返回None >>> l = [11,22,33,22,44] >>> res=l.remove(22) # 从左往右查找第一个括号内需要删除的元素 >>> print(res) None # 7.循环 # 循环遍历my_friends列表里面的值 for line in my_friends: print(line) 'tony' 'jack' 'jason' 4 # 8.reverse()颠倒列表内元素顺序,不是排序,列表倒过来。 >>> l = [11,22,33,44] >>> l.reverse() >>> l [44,33,22,11] # 8.sort()给列表内所有元素排序 # 8.1 排序时列表元素之间必须是相同数据类型,不可混搭,否则报错 >>> l = [11,22,3,42,7,55] >>> l.sort() >>> l [3, 7, 11, 22, 42, 55] # 默认从小到大排序 >>> l = [11,22,3,42,7,55] >>> l.sort(reverse=True) # reverse用来指定是否跌倒排序,默认为False >>> l [55, 42, 22, 11, 7, 3] # 8.2 了解知识: # 我们常用的数字类型直接比较大小,但其实,字符串、列表等都可以比较大小, 原理相同:都是依次比较对应位置的元素的大小,如果分出大小,则无需比较下一个元素,比如 >>> l1=[1,2,3] >>> l2=[2,] >>> l2 > l1 True # 字符之间的大小取决于它们在ASCII表中的先后顺序,越往后越大 >>> s1='abc' >>> s2='az' >>> s2 > s1 # s1与s2的第一个字符没有分出胜负,但第二个字符'z'>'b.txt',所以s2>s1成立 True 了解:列表也可以比大小,原理同字符串一样,必须同种类型 # 所以我们也可以对下面这个列表排序 >>> l = ['A','z','adjk','hello','hea'] >>> l.sort() >>> l ['A', 'adjk', 'hea', 'hello','z'] # 9、count index clear # l = [1, 1, 22, 1, 24] # # res1 = l.count(1) # 1有几个 3 [1, 1, 22, 1, 24] # # res2 = l.index(22) # 找索引,找不到报错 2 [1, 1, 22, 1, 24] # res3 = l.clear() # 清除列表,返回一个None None [] # # print(res1,l) # # print(res2,l) # print(res3,l) # 补充 # 1、队列:FIFO,先进先出(商场自动扶梯,先站上去的人,先出去) l=[] # 入队操作 l.append('first') l.append('second') l.append('third') print(l) # 出队操作 print(l.pop(0)) print(l.pop(0)) print(l.pop(0)) # 2、堆栈:LIFO,后进后出(向衣柜里叠衣服,后叠进去的,先拿出来) l = [] # 入栈操作 l.append('first') l.append('second') l.append('third') print(l) # 出栈操作 print(l.pop()) print(l.pop()) print(l.pop())
练习
# 1. 有列表data=['alex',49,[1900,3,18]],分别取出列表中的名字,年龄,出生的年,月,日赋值给不同的变量 data = ['alex', 49, [1900, 3, 18]] name = data[0] age = data[1] year = data[2][0] month = data[2][1] day = data[2][2] # 2. 用列表模拟队列 l = [] l.append('a') l.append('b') l.append('c') l.pop(0) l.pop(0) l.pop(0) # 3. 用列表模拟堆栈 l1 = [] l1.append('a') l1.append('b') l1.append('c') l1.pop() l1.pop() l1.pop() # 4. 有如下列表,请按照年龄排序(涉及到匿名函数) l2 = [ {'name': 'alex', 'age': 84}, {'name': 'oldboy', 'age': 73}, {'name': 'egon', 'age': 18}, ] l2.sort(key=lambda item: item['age']) print(l2)
五 元组
1、元组与列表类似("一个不可变的列表”),也是可以存多个任意类型的元素,不同之处在于元组的元素不能修改。
# 即元组相当于不可变的列表,用于记录多个固定不允许修改的值,单纯用于取,只用于读不用于改
2、定义:
在()内用逗号分隔开多个任意类型的值
# >>> countries = ("中国","美国","英国") # 本质:countries = tuple("中国","美国","英国")
强调:如果元组内只有一个值,则必须加一个逗号,否则()就只是包含的意思而非定义元组
# >>> countries = ("中国",) # 本质:countries = tuple("中国")
强调,元组不能改,是指元组对应内存地址不能改,元组里含有列表等可变类型数据,在列表内的内容可以改变
3、类型转换
# 但凡能被for循环的遍历的数据类型都可以传给tuple()转换成元组类型 >>> tuple('wdad') # 结果:('w', 'd', 'a', 'd') >>> tuple([1,2,3]) # 结果:(1, 2, 3) >>> tuple({"name":"jason","age":18}) # 结果:('name', 'age') >>> tuple((1,2,3)) # 结果:(1, 2, 3) >>> tuple({1,2,3,4}) # 结果:(1, 2, 3, 4) # tuple()会跟for循环一样遍历出数据类型中包含的每一个元素然后放到元组中
4、使用
>>> tuple1 = (1, 'hhaha', 15000.00, 11, 22, 33) 4.1 按索引取值(正向取+反向取):只能取,不能改否则报错! >>> tuple1[0] 1 >>> tuple1[-2] 22 >>> tuple1[0] = 'hehe' # 报错:TypeError: 4.2 切片(顾头不顾尾,步长) >>> tuple1[0:6:2] (1, 15000.0, 22) 4.3 长度 >>> len(tuple1) 6 4.4 成员运算 in 和 not in >>> 'hhaha' in tuple1 True >>> 'hhaha' not in tuple1 False
5、循环
>>> for line in tuple1: ... print(line) 1 hhaha 15000.0 11 22 33
6、内置方法(两种)
t = (1, 2, 34, 5) t1 = t.count(1) t2 = t.index(34) print(t1, type(t1)) print(t2, type(t2))
练习
# 简单购物车,要求如下: # 实现打印商品详细信息,用户输入商品名和购买个数,则将商品名,价格,购买个数加入购物列表,如果输入为空或其他非法输入则要求用户重新输入 msg_dic = { 'apple': 10, 'tesla': 100000, 'mac': 3000, 'lenovo': 30000, 'chicken': 10, } l = [] while True: for key, item in msg_dic.items(): print('商品名:{}, 价格:{}元!'.format(key, item)) product_name = input('请输入商品名:').strip() if not product_name or product_name not in msg_dic:continue count = input('购买个数:').strip() if not count.isdigit():continue l.append((product_name, msg_dic[product_name], count)) print(l)
六 字典
1、作用
2、定义:在{}内用逗号分隔开多元素,每一个元素都是key:value的形式,其中value可以是任意类型
# 而key则必须是不可变类型,key不重复,详见第八小节,通常key应该是str类型,因为str类型会对value有描述性的功能
info={'name':'tony','age':18,'sex':'male'} #本质info=dict({....}) # 也可以这么定义字典 info=dict(name='tony',age=18,sex='male') # info={'age': 18, 'sex': 'male', 'name': 'tony'} d={} #默认定义出来的是空字典 d1=dict() #也定义空字典 print(d,d1)
3、数据类型转换
转换1:
info = [['name', 'tony'], ('age', 18), ['sex', 'male']] d = {} for item in info: d[item[0]] = item[1] print(d) # {'name': 'tony', 'age': 18, 'sex': 'male'} res = dict(info) print(res) # {'name': 'tony', 'age': 18, 'sex': 'male'} 转换2:fromkeys会从元组中取出每个值当做key,然后与None组成key:value放到字典中 >>> {}.fromkeys(('name','age','sex'),None) {'age': None, 'sex': None, 'name': None}
4、内置方法
# 1.1 取 >>> dic = { ... 'name': 'xxx', ... 'age': 18, ... 'hobbies': ['play game', 'basketball'] ... } >>> dic['name'] 'xxx' >>> dic['hobbies'][1] 'basketball' # 1.2 对于赋值操作,如果key原先不存在于字典,则会新增key:value >>> dic['gender'] = 'male' #列表对没有的索引赋值,会报错;类似与列表的append,insert >>> dic {'name': 'tony', 'age': 18, 'hobbies': ['play game', 'basketball'],'gender':'male'} # 1.3 对于赋值操作,如果key原先存在于字典,则会修改对应value的值 >>> dic['name'] = 'tony' >>> dic {'name': 'tony', 'age': 18, 'hobbies': ['play game', 'basketball']} # 2、长度len >>> len(dic) 3 # 3、成员运算in和not in >>> 'name' in dic # 判断某个值是否是字典的key True # 4、删除 # 4.1 通用删除 dic={'name':'tony','age':18,'sex':'male'} del dic['name'] print(dic) # 4.2 >>> res=dic.pop('name') # 通过指定字典的key来删除字典的键值对,返回删除key对应的那个Value。 >>> dic {'age': 18, 'hobbies': ['play game', 'basketball']} >>> res 'tony' # 4.3 popitem删除:随机删除,返回元组(删除的Key,删除Value) res = dic.popitem() print(res) # ('sex', 'male') # 5、键keys(),值values(),键值对items() --》在python3中得到的是老母鸡,跟range一样的道理,节约内存 >>> dic = {'age': 18, 'hobbies': ['play game', 'basketball'], 'name': 'xxx'} # 获取字典所有的key >>> dic.keys() #python2中输出是--》['name', 'age', 'hobbies'] dict_keys(['name', 'age', 'hobbies']) # 获取字典所有的value >>> dic.values() dict_values(['xxx', 18, ['play game', 'basketball']]) # 获取字典所有的键值对 >>> dic.items() dict_items([('name', 'xxx'), ('age', 18), ('hobbies', ['play game', 'basketball'])])
需要掌握得
1.get() >>> dic= {'k1':'jason','k2':'Tony','k3':'JY'} #根据key取值,容错性好 >>> dic.get('k1') 'jason' # key存在,则获取key对应的value值 >>> res=dic.get('xxx') # key不存在,不会报错而是默认返回None >>> print(res) None >>> res=dic.get('xxx',666) # key不存在时,可以设置默认返回的值 >>> print(res) 666
ps:字典取值建议使用get方法
# 2.update() # 用新字典更新旧字典,有则修改,无则添加 >>> dic= {'k1':'jason','k2':'Tony','k3':'JY'} >>> dic.update({'k1':'JN','k4':'xxx'}) >>> dic {'k1': 'JN', 'k3': 'JY', 'k2': 'Tony', 'k4': 'xxx'} # 3.setdefault() # key不存在则新增键值对,并将新增的value返回 >>> dic={'k1':111,'k2':222} >>> res=dic.setdefault('k3',333) >>> res 333 >>> dic # 字典中新增了键值对 {'k1': 111, 'k3': 333, 'k2': 222} # key存在则不做任何修改,并返回已存在key对应的value值 >>> dic={'k1':111,'k2':222} >>> res=dic.setdefault('k1',666) >>> res 111 >>> dic # 字典不变 {'k1': 111, 'k2': 222}
练习
# 1 有如下值集合 [11,22,33,44,55,66,77,88,99,90],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中 # 即: {'k1': 大于66的所有值, 'k2': 小于66的所有值} l = [11, 22, 33, 44, 55, 66, 77, 88, 99, 90] l1 = [] l2 = [] for i in l: if i > 60: l1.append(i) if i < 60: l2.append(i) dic = {} dic['k1'] = l1 dic['k2'] = l2 print(dic) # 2 统计s='hello alex alex say hello sb sb'中每个单词的个数 # 结果如:{'hello': 2, 'alex': 2, 'say': 1, 'sb': 2} s = 'hello alex alex say hello sb sb' l3 = s.split(' ') print(l3) dic = {} for i in l3: dic[i] = l3.count(i) # 字典给键赋值,就是给字典增加键值对 print(dic)
七 集合
1、作用
集合、list、tuple、dict一样都可以存放多个值,但是集合主要用于:去重、关系运算
2、定义
定义:在{}内用逗号分隔开多个元素,集合具备以下三个特点:
1:每个元素必须是不可变类型
2:集合内没有重复的元素
3:集合内元素无序
s = {1,2,3,4} # 本质 s = set({1,2,3,4})
# 注意1:列表类型是索引对应值,字典是key对应值,均可以取得单个指定的值,
而集合类型既没有索引也没有key与值对应,所以无法取得单个的值,而且对于集合来说,主要用于去重与关系运算,
根本没有取出单个指定值这种需求。
# 注意2:{}既可以用于定义dict,也可以用于定义集合,但是字典内的元素必须是key:value的格式,
现在我们想定义一个空字典和空集合,该如何准确去定义两者?
d = {} # 默认是空字典
s = set() # 这才是定义空集合
3、类型转换
# 但凡能被for循环的遍历的数据类型(强调:遍历出的每一个值都必须为不可变类型)都可以传给set()转换成集合类型
# >>> s = set([1,2,3,4])
# >>> s1 = set((1,2,3,4))
# >>> s2 = set({'name':'jason',})
# >>> s3 = set('egon')
# >>> s,s1,s2,s3
{1, 2, 3, 4} {1, 2, 3, 4} {'name'} {'e', 'o', 'g', 'n'}
4、使用
关系运算(类似于数学集合运算)
我们定义两个集合friends与friends2来分别存放两个人的好友名字,然后以这两个集合为例讲解集合的关系运算
friends1 = {"zero", "kevin", "jason", "egon"} # 用户1的好友们
friends2 = {"Jy", "ricky", "jason", "egon"} # 用户2的好友们
1)合集/并集(|):求两个用户所有的好友(重复好友只留一个)
# print(friends1|friends2) #无序得
# print(friends1.union(friends2))
2)交集(&):求两个用户的共同好友
print(friends1&friends2)
print(friends1.intersection(friends2)) #等价
3)差集(-):
# print(friends1 - friends2) # 求用户1独有的好友
# print(friends1.difference(friends2))
# print(friends2 - friends1) # 求用户2独有的好友
# print(friends2.difference(friends1))
4)对称差集(^) # 求两个用户独有的好友们(即去掉共有的好友)
print(friends1 ^ friends2)
5)值是否相等(==)
# >>> friends1 == friends2
# False
6)父集:一个集合是否包含另外一个集合
6.1 包含则返回True
>>> {1,2,3} > {1,2}
True
print({1,2,3}.issuperset({1,2})
print({1,2}.issubset({1,2,3})
>>> {1,2,3} >= {1,2}
True
6.2 不存在包含关系,则返回False
>>> {1,2,3} > {1,3,4,5}
False
>>> {1,2,3} >= {1,3,4,5}
False
7)子集
>>> {1,2} < {1,2,3}
True
>>> {1,2} <= {1,2,3}
True
8)长度
>>> s={'a','b.txt','c'}
>>> len(s)
3
9)成员运算
>>> 'c' in s
True
10)循环
>>> for item in s:
... print(item)
...
c
a
b.txt
5 去重(局限性)
# 1. 只能针对不可变类型
# 2. 集合本身是无序的,去重之后无法保留原来的顺序
>>> l=['a','b.txt',1,'a','a']
>>> s=set(l)
>>> s # 将列表转成了集合
{'b.txt', 'a', 1}
>>> l_new=list(s) # 再将集合转回列表
>>> l_new
['b.txt', 'a', 1] # 去除了重复,但是打乱了顺序
# 针对不可变类型,并且保证顺序则需要我们自己写代码实现,例如
l=[
{'name':'lili','age':18,'sex':'male'},
{'name':'jack','age':73,'sex':'male'},
{'name':'tom','age':20,'sex':'female'},
{'name':'lili','age':18,'sex':'male'},
{'name':'lili','age':18,'sex':'male'},
]
new_l=[]
for dic in l:
if dic not in new_l:
new_l.append(dic)
print(new_l)
# 结果:既去除了重复,又保证了顺序,而且是针对不可变类型的去重
[
{'age': 18, 'sex': 'male', 'name': 'lili'},
{'age': 73, 'sex': 'male', 'name': 'jack'},
{'age': 20, 'sex': 'female', 'name': 'tom'}
]
6 其他内置方法
# s={1,2,3}
1)discard
# s.discard(4) #删除元素不存在do nothing
# print(s)
# s.remove(4) #删除元素不存在则报错
2)update
# s.update({1,3,5})
# print(s)
3)pop
# res=s.pop()
# print(res)
# print(s)
4)add
# s.add(4)
# print(s)
练习
一.关系运算 有如下两个集合,pythons是报名python课程的学员名字集合,linuxs是报名linux课程的学员名字集合 pythons={'alex','egon','yuanhao','wupeiqi','gangdan','biubiu'} linuxs={'wupeiqi','oldboy','gangdan'} 1. 求出即报名python又报名linux课程的学员名字集合 2. 求出所有报名的学生名字集合 3. 求出只报名python课程的学员名字 4. 求出没有同时这两门课程的学员名字集合
# 有如下两个集合,pythons是报名python课程的学员名字集合,linuxs是报名linux课程的学员名字集合 pythons={'alex','egon','yuanhao','wupeiqi','gangdan','biubiu'} linuxs={'wupeiqi','oldboy','gangdan'} # 求出即报名python又报名linux课程的学员名字集合 print(pythons & linuxs) # 求出所有报名的学生名字集合 print(pythons | linuxs) # 求出只报名python课程的学员名字 print(pythons - linuxs) # 求出没有同时这两门课程的学员名字集合 print(pythons ^ linuxs)
二.去重 1. 有列表l=['a','b',1,'a','a'],列表元素均为可hash类型,去重,得到新列表,且新列表无需保持列表原来的顺序 2.在上题的基础上,保存列表原来的顺序 3.去除文件中重复的行,肯定要保持文件内容的顺序不变 4.有如下列表,列表元素为不可hash类型,去重,得到新列表,且新列表一定要保持列表原来的顺序 l=[ {'name':'egon','age':18,'sex':'male'}, {'name':'alex','age':73,'sex':'male'}, {'name':'egon','age':20,'sex':'female'}, {'name':'egon','age':18,'sex':'male'}, {'name':'egon','age':18,'sex':'male'}, ]
#去重,无需保持原来的顺序 l=['a','b',1,'a','a'] print(set(l)) #去重,并保持原来的顺序 #方法一:不用集合 l=[1,'a','b',1,'a'] l1=[] for i in l: if i not in l1: l1.append(i) print(l1)
#方法二:借助集合 l1=[] s=set() for i in l: if i not in s: s.add(i) l1.append(i) print(l1) # 同上方法二,去除文件中重复的行 import os with open('db.txt','r',encoding='utf-8') as read_f,\ open('.db.txt.swap','w',encoding='utf-8') as write_f: s=set() for line in read_f: if line not in s: s.add(line) write_f.write(line) os.remove('db.txt') os.rename('.db.txt.swap','db.txt') # 列表中元素为可变类型时,去重,并且保持原来顺序 l=[ {'name':'egon','age':18,'sex':'male'}, {'name':'alex','age':73,'sex':'male'}, {'name':'egon','age':20,'sex':'female'}, {'name':'egon','age':18,'sex':'male'}, {'name':'egon','age':18,'sex':'male'}, ] # print(set(l)) #报错:unhashable type: 'dict' s=set() l1=[] for item in l: val=(item['name'],item['age'],item['sex']) if val not in s: s.add(val) l1.append(item) print(l1) # 定义函数,既可以针对可以hash类型又可以针对不可hash类型 def func(items,key=None): s=set() for item in items: val=item if key is None else key(item) if val not in s: s.add(val) yield item print(list(func(l,key=lambda dic:(dic['name'],dic['age'],dic['sex']))))
八 数据类型总结
按存储空间的占用分(从低到高)
数字 字符串 集合:无序,即无序存索引相关信息 元组:有序,需要存索引相关信息,不可变 列表:有序,需要存索引相关信息,可变,需要处理数据的增删改 字典:无序,需要存key与value映射的相关信息,可变,需要处理数据的增删改
按存值个数区分
标量/原子类型 | 数字,字符串 |
容器类型 | 列表,元组,字典 |
按可变不可变区分
可变 | 列表,字典 |
不可变 | 数字,字符串,元组 |
按访问顺序区分
直接访问 | 数字 |
顺序访问(序列类型) | 字符串,列表,元组 |
key值访问(映射类型) | 字典 |
九、 作业
#作业一: 三级菜单 #要求: 打印省、市、县三级菜单 可返回上一级 可随时退出程序
menu = { '北京':{ '海淀':{ '五道口':{ 'soho':{}, '网易':{}, 'google':{} }, '中关村':{ '爱奇艺':{}, '汽车之家':{}, 'youku':{}, }, '上地':{ '百度':{}, }, }, '昌平':{ '沙河':{ '老男孩':{}, '北航':{}, }, '天通苑':{}, '回龙观':{}, }, '朝阳':{}, '东城':{}, }, '上海':{ '闵行':{ "人民广场":{ '炸鸡店':{} } }, '闸北':{ '火车战':{ '携程':{} } }, '浦东':{}, }, '山东':{}, } # 方法一 tag=True while tag: menu1=menu for key in menu1: # 打印第一层 print(key) choice1=input('第一层>>: ').strip() # 选择第一层 if choice1 == 'b': # 输入b,则返回上一级 break if choice1 == 'q': # 输入q,则退出整体 tag=False continue if choice1 not in menu1: # 输入内容不在menu1内,则继续输入 continue while tag: menu_2=menu1[choice1] # 拿到choice1对应的一层字典 for key in menu_2: print(key) choice2 = input('第二层>>: ').strip() if choice2 == 'b': break if choice2 == 'q': tag = False continue if choice2 not in menu_2: continue while tag: menu_3=menu_2[choice2] for key in menu_3: print(key) choice3 = input('第三层>>: ').strip() if choice3 == 'b': break if choice3 == 'q': tag = False continue if choice3 not in menu_3: continue while tag: menu_4=menu_3[choice3] for key in menu_4: print(key) choice4 = input('第四层>>: ').strip() if choice4 == 'b': break if choice4 == 'q': tag = False continue if choice4 not in menu_4: continue # 第四层内没数据了,无需进入下一层 # 方法二 #part1(初步实现):能够一层一层进入 layers = [menu, ] while True: current_layer = layers[-1] for key in current_layer: print(key) choice = input('>>: ').strip() if choice not in current_layer: continue layers.append(current_layer[choice]) #part2(改进):加上退出机制 layers=[menu,] while True: if len(layers) == 0: break current_layer=layers[-1] for key in current_layer: print(key) choice=input('>>: ').strip() if choice == 'b': layers.pop(-1) continue if choice == 'q':break if choice not in current_layer:continue layers.append(current_layer[choice])