#python3编码
#数据类型:bytes,str拥有的所有方法bytes都有,编码使用类型
#Unicode占用字节过多,不可用于文件的存储及传输,python的str类型就是Unicode编码,故需要bytes类型做转换
#bytes类型编码可使用utf-8、gbk、gb2312等非Unicode编码类型;
name = 'Jerry'
name1 = b'Jerry'#英文bytes类型
print(name, type(name), name1, type(name1))
a = '我'.encode('utf-8')#中文bytes类型
print(a, type(a))
#str转bytes类型,编码
a = '哈哈'
s1 = a.encode('utf-8')
s2 = a.encode('gbk')
print(a, s1, s2)
#bytes转str,解码
s3 = s1.decode('utf-8')
s4 = s2.decode('gbk')
print(s3, s4)
#数据类型补充
#1、元组里只有一个元素且没有逗号,则该数据的类型和里面的元素相同
a = ('test')
b = ('test',)
print(a, type(a))#test <class 'str'>
print(b, type(b))#('test',) <class 'tuple'>
#2、list,循环列表时,最好不要改变列表的大小(如循环删除,要倒序操作)
L1 = [111, 222, 333, 444, 555, 666, 777]
#删除奇数索引,错误方式
"""
for index in range(len(L1)-1):
if index % 2 == 1:
L1.pop(index)
"""
#正确方式
del L1[1::2]
print(L1)
#3、dict.fromkeys('keys_list', value),参数1是可迭代对象,做为列表的key,这些key的value均为参数2
dic = dict.fromkeys('abc', 123)
dic1 = dict.fromkeys([11, 22, 33], 123)
print(dic, dic1)#{'a': 123, 'b': 123, 'c': 123} {11: 123, 22: 123, 33: 123}
#fromkeys()的value如果是容器类,则是同一个容器,操作一个会全部改变
dic2 = dict.fromkeys('def', [])
print(dic2)#{'d': [], 'e': [], 'f': []}
dic2['d'].append('1')
print(dic2)#{'d': ['1'], 'e': ['1'], 'f': ['1']}
#非容器类不影响
dic['a'] = 1
print(dic)#{'a': 1, 'b': 123, 'c': 123}
#数据类型转换:str→list split, list→str join
#dict→list,把字典的key放入列表
L1 = list(dic2)
print(L1)#['d', 'e', 'f']
#集合,可变数据类型,容器类,以{ }存在,里面是一个一个的元素,空集合是set{}
a = {}#默认类型是字典
print(type(a))#<class 'dict'>
#集合内元素必须是不可变类型
# ***可以是不可变类型的变量
a = 5
set1 = {1, 2, 3, a, 'b', ('c', 'd')}
a = 6
print(set1, type(set1))#{('c', 'd'), 1, 2, 3, 'b', 5} <class 'set'>
#集合无序且不可重复
set2 = {11, 22, 33, 22, 33}
print(set2)#{11, 12, 13}
#可用做列表去重
L1 = [11, 22, 33, 11, 22, 33]
L2 = list(set(L1))
print(L2)#[11, 12, 13]
#集合的增删查
#增
set3 = {'test1', 1}
set3.add('test2')#元素添加
set3.update('abc')#对象遍历添加
print(set3)#{'test1', 1, 'test2', 'a', 'b', 'c'}
#删
set3.remove('test1')
print(set3)#{1, 'test2', 'a', 'b', 'c'}
print(set3.pop())#随机删除,有返回值,b
print(set3)#{1, 'test2', 'a', 'c'}
#查
for i in set3:
print(i)
#清空clear
set3.clear()
print(set3)#set()
#删除整个列表
del set3
#集合运算
#交集 & intersection()
set4 = {1, 2, 3}
set5 = {2, 3, 4}
print(set4 & set5)#{2, 3}
print(set4.intersection(set5))#{2, 3}
#并集 | union()
print(set4 | set5)#{1, 2, 3, 4}
print(set4.union(set5))#{1, 2, 3, 4}
#差集 - difference()
print(set4 - set5)#{1}
print(set5.difference(set4))#{4}
#反交集 ^ symmetric_difference()
print(set4 ^ set5)#{1, 4}
print(set4.symmetric_difference())#{1, 4}
#子集 < issubest()
set6 = {1, 2}
set7 = {1, 2, 3}
print(set6 < set7)#True
print(set6.issubest(set7))#True
#超集 > issuperset()
print(set7 > set6)#True
print(set7.issuperset(set6))#True
#frozenset()集合冻结,变成不可变类型,可以做为集合、元组的元素或者字典的key
set8 = frozenset(set7)
print(set8, type(set8))#frozenset({1, 2, 3, 4}) <class 'frozenset'>
#赋值指向同一内存地址时,操作改变会影响所以使用该内存变量
L1 = [1, 2, 3]
L2 = L1
L2.append(4)
print(L1, L2)#[1, 2, 3, 4] [1, 2, 3, 4]
#深浅copy
#浅copy
import copy
L3 = [11, 22, 33]
L4 = L3.copy()
print(L3 is L4)#False
#只创建第一层内存地址,从第二层开始指向的是同一个内存地址
L5 = [1, 2, [3, 4]]
L6 = L5.copy()
print(L5 is L6)#False
print(L5[-1] is L6[-1])#True
L5[-1].append(5)
print(L5, L6)#[1, 2, [3, 4, 5]] [1, 2, [3, 4, 5]]
#深copy.deepcopy(),完全独立
L7 = copy.deepcopy(L5)
print(L5 is L7)#False
print(L5[-1] is L7[-1])#False
L7[-1].append(6)
print(L5, L7)#[1, 2, [3, 4, 5]] [1, 2, [3, 4, 5, 6]]
#扩展
L8 = [1, 2, [3, 4]]
L9 = L8[:]
L8[-1].append(5)
print(L8, L9)#[1, 2, [3, 4, 5]] [1, 2, [3, 4, 5]] *都改变
L8.append(6)
print(L8, L9)#[1, 2, [3, 4, 5], 6] [1, 2, [3, 4, 5]] *只L8改变,所以切片操作是浅copy