bytes, bytearray, 切片, 封装,解构,set,dict知识总结
2017-10-16 20:49
176 查看
bytes,bytearray
基本概念
python3引入的两个新类型:bytes: 不可变字节序列.
bytearray: 字节组,可变.
字符串与bytes:
字符串是字符组成的有序序列,字符可以使用编码来理解.
bytes是字节组成的有序的不可变序列.
bytearray是字节组成的有序的可变序列.
编码与解码:
字符串按照不同的字符集编码encode返回字节序列bytes.
encode(encoding='utf-8', errors='strict')-> bytes.
字节序列按照不同的字符集解码decode返回字符串.
bytes.decode(encoding='utf-8',errors='strict')-> str
bytearray.decode(encoding='utf-8',errors='strict')-> str
bytes定义
bytes() emptybytes.bytes(int)指定字节的bytes,用0填充.
bytes(iterable_of_ints)-> bytes[0,255]的int组成的iterable对象.
bytes(string,encoding[,errors]) -> bytes等价于string.encode().
bytes(bytes_or_buffer)-> immutable copy of bytes_or_buffer 从一个字节序列或buffer中复制出一个新的不可变的bytes对象.
使用b前缀定义:
只允许基本ASCII使用形式b'abc9'.
使用16进制表示b'\x41\x61'.
bytes操作
和str类型类似,都是不可变类型,所以方法很多都一样,只是bytes的方法,输入和输出的都是bytes.b'abcdef'.replace(b'f', b'k').
b'abc'.find(b'b')
类方法 bytes.fromhex(string)
string必须是2个字符的16进制的形式,'6162 6a 6b',空格将被忽略.
bytes.fromhex('6162 09 6a 6b00').
hex()
返回16进制表示的字符串.
'abc'.encode().hex()
索引:
b'abcdef'[2] 返回该字节对应的数,int类型.
bytearr定义
bytearray()空bytearray.bytearray(int)指定字节的bytearray,被0填充.
bytearray(iterable_of_ints)-> bytearray[0,255]的int组成的iterable对象.
bytearray(string,encoding[,errors]) -> bytearray近似于string.encode(),不过返回可变对象.
bytearray(bytes_or_buffer)从一个字节序列或buffer中复制出一个新的可变的bytearray对象.
注: b前缀定义的类型是bytes类型.
bytearray操作
和bytes类型的方法相同bytearray(b'abcdef').replace(b'f', b'k').
bytearray(b'abc').find(b'b')
类方法 bytearray.fromhex(string)
string必须是2个字符的16进制的形式,'6162 6a 6b',空格将被忽略.
bytearray.fromhex('6162 09 6a 6b00').
hex()
返回16进制表示的字符串.
bytearray('abc'.encode()).hex()
索引:
bytearray(b'abcdef')[2] # 返回该字节对应的数,int类型.
append(int)# 尾部追加一个元素.
insert(index,int) # 在指定索引位置插入元素.
extend(iterable_of_ints) # 将一个可迭代的整数集合追加到当前bytearray.
pop(index=-1) # 从指定索引上移除元素,默认从尾部移除.
remove(value) # 找到第一个value移除,找不到抛异常ValueError.
注: 上述方法若使用int类型,值在[0, 255].
clear() # 清空bytearray.
reverse() # 翻转bytearray,就地修改.
1234567891011121314151617181920 | In [1]: b = bytearray() In [2]: b.append(97) In [3]: b Out[3]: bytearray(b'a') In [4]: b.decode() Out[4]: 'a' In [5]: bytearray(range(97, 123)) Out[5]: bytearray(b'abcdefghijklmnopqrstuvwxyz') In [6]: bytearray(range(97, 123)).decode() Out[6]: 'abcdefghijklmnopqrstuvwxyz' In [7]: bytearray(range(65,91)).decode() Out[7]: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' In [8]: |
切片
线性结构
可迭代 for .. inlen()可以获取长度.
通过下标可以访问.
可以切片.
学过的线性结构: list, tuple, str, bytes,bytearray.
切片
通过索引区间访问线性结构的一段数据.sequence[start:stop] # 表示返回[start, stop)区间的子序列.
支持负索引.
start为0,可以省略.
stop为末尾,可以省略.
start一定在stop的左边.
[:]表示从头至尾,全部元素被取出,等效于copy()方法.
步长切片: [start:stop:step]
step为步长,可以是正负整数,默认为1. step要和start:stop同向,否则返回空序列.
12345678910111215161718 | In [22]: bytearray(range(65, 90)).decode() Out[22]: 'ABCDEFGHIJKLMNOPQRSTUVWXY' In [23]: bytearray(range(65, 90)).decode()[10:20] Out[23]: 'KLMNOPQRST' In [24]: bytearray(range(65, 90)).decode()[10:20:3] Out[24]: 'KNQT' In [25]: bytearray(range(65, 90)).decode()[-15:-5] Out[25]: 'KLMNOPQRST' In [26]: bytearray(range(65, 90)).decode()[-15:-5:3] Out[26]: 'KNQT' In [27]: |
封装和解构
封装
将多个值使用逗号分割,组合在一起.本质上,返回一个元组,只是省略了小括号.
python特有语法,被很多语言学习和借鉴.
1234567891011121314151617 | In [6]: t1 = (1, 2) In [7]: t2 = 1, 2 In [8]: t1 Out[8]: (1, 2) In [9]: t2 Out[9]: (1, 2) In [10]: type(t1) Out[10]: tuple In [11]: type(t2) Out[11]: tuple In [12]: |
12345678910111213 | In [17]: a = 4 In [18]: b = 5 In [19]: temp = a In [20]: a = b In [21]: b = temp # 或 In [22]: a, b = b, a # 等号右边使用了封装,左边使用了解构. |
解构
把线性结构的元素解开,并顺序赋给其他变量.左边接纳的变量数要和右边解开的元素个数一致.
123456 | n [23]: lst = [3, 5] In [24]: first, second = lst In [25]: print(first, second) 3 5 |
123456789101112131415161718192021222324252627 | In [28]: a, b = 1, 2 In [29]: a, b = (1, 2) In [30]: a, b = [1, 2] In [31]: a, b = {10, 20} In [32]: a, b = {'a': 10, 'b': 20} In [33]: a, b = {10, 20, 30} --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-33-266c898e7d19> in <module>() ----> 1 a, b = {10, 20, 30} ValueError: too many values to unpack (expected 2) In [34]: a, *b = {10, 20, 30} In [35]: [a, b] = (1, 2) In [36]: [a, b] = 10, 20 In [37]: (a, b) = {30, 40} In [38]: |
python3的解构
使用"*变量名"接收,但不能单独使用.被"*变量名"收集后组成一个列表.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 | In [6]: lst = list(range(1, 101, 2)) In [8]: head, *mid, tail = lst In [9]: head Out[9]: 1 In [10]: tail Out[10]: 99 In [11]: *lst2 = lst File "<ipython-input-10-98211a44ccfb>", line 1 *lst2 = lst ^ SyntaxError: starred assignment target must be in a list or tuple In [12]: *lst2 = lst File "<ipython-input-12-98211a44ccfb>", line 1 *lst2 = lst ^ SyntaxError: starred assignment target must be in a list or tuple In [13]: *body, tail = lst In [14]: tail Out[14]: 99 In [15]: head, *tail = lst In [16]: head Out[16]: 1 In [17]: head, *m1, *m2, tail = lst File "<ipython-input-17-1fc1a52caa8e>", line 1 head, *m1, *m2, tail = lst ^ SyntaxError: two starred expressions in assignment In [18]: head, *mid, tail = 'abcdefghijklmn' In [19]: type(mid) Out[19]: list In [20]: type(head) Out[20]: str In [21]: |
丢弃变量
这是一个惯例,是一个不成文的约定,不是标准.如果不关心一个变量,就可以定义修改变量的名字为下划线(_).
"_"是一个合法的标识符,也可以作为一个有效的变量使用,但是定义成下划线就是希望不要被使用,除非你明确的知道这个数据需要被使用.
12345678910111213141516 | In [24]: lst = [9, 8, 7, 20] In [25]: first, *second = lst In [26]: head, *_, tail = lst In [27]: head Out[27]: 9 In [28]: tail Out[28]: 20 In [29]: _ # 下划线是合法的标识符,看到下划线就知道这个变量不希望被使用. Out[29]: [8, 7] In [30]: |
1234567891011121314 | In [32]: lst = [9, 8, 7, 20] In [33]: first, *second = lst In [34]: _, *_, tail = lst In [35]: _ Out[35]: [8, 7] In [36]: tail Out[36]: 20 In [37]: _ Out[37]: [8, 7] |
_这个变量本身无任何语义,没有任何可读性,所以不是用来给人使用的.
python中很多库,都使用这个变量,使用十分广泛,所以不要在不明确变量作用域的情况下,使用_导致和库中_冲突.
_, [*_, a], _ = lst # []或()都可以.
练习
集 – set
基本概念
约定:set翻译为集合.
collections翻译为集合类型,是一个大概念.
set:
可变, 无序, 不重复的元素的集合.
定义,初始化
set() -> new empty set object.set(iterable) -> new set object.
set的元素要求必须可hash.
目前学过的不可hash类型有list,set.
元素不可以索引.
set可迭代.
12345678910111213141516171819202122232425262728 | In [41]: s2 = set(range(5)) In [42]: s3 = set(list(range(10))) In [43]: s2 Out[43]: {0, 1, 2, 3, 4} In [44]: s3 Out[44]: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} In [45]: s4 = {} In [46]: type(s4) Out[46]: dict In [47]: s5 = {9, 10, 11} In [48]: s6 = {(1, 2), 3, 'a'} In [49]: s7 = {[1], (1,), 1} --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-49-67713ab500d7> in <module>() ----> 1 s7 = {[1], (1,), 1} TypeError: unhashable type: 'list' # set里面只能放置可哈希元素,list不可哈希,故报错. In [50]: |
增加
add(elem)增加一个元素到set中.
如果元素存在,什么也不做.
update(*others)
合并其他元素到set集合中来.
参数others必须是可迭代对象.
就地修改.
1234567891011121314151617 | In [64]: s1 = {1, 2, 3} In [65]: s1.add('a') In [66]: s1 Out[66]: {1, 2, 3, 'a'} In [67]: s2 = {4, 5, 6} In [68]: s3 = {7, 8, 9} In [69]: s1.update(s2, s3) In [70]: s1 Out[70]: {1, 2, 3, 4, 5, 6, 7, 8, 9, 'a'} In [71]: |
删除
remove(elem)从set中移除第一个元素.
元素不存在,抛出KeyError异常,因为set中的元素被hash过,类似dict中的key.
discard(elem)
从set中移除一个元素
元素不存在,什么都不做.
pop() -> item
移除并返回任意的元素.
空集返回KeyError异常.
clear()
移除所有元素.
12345678910111213141516171819202122232425262728293031 | In [73]: s1 = {'one', 'two', 'three', 'four', 'five'} In [74]: s1.remove('one') In [75]: s1.remove('one') --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-75-8a1942935899> in <module>() ----> 1 s1.remove('one') KeyError: 'one' In [76]: s1.discard('two') In [77]: s1.discard('two') In [78]: s1.pop() Out[78]: 'five' In [79]: s1.pop() Out[79]: 'four' In [80]: s1 Out[80]: {'three'} In [81]: s1.clear() In [82]: s1 Out[82]: set() In [83]: |
修改,查询
修改:要么删除,要么加入新的元素.
set元素不可重复,故没有修改方法.
查询:
非线性结构,无法索引.
遍历:
可以迭代所有元素.
成员运算符:
in和not in判断元素是否在set中.
效率高.
list和set关于成员运算符的比较: set要比list效率高.
set和线性结构
线性结构的查询时间复杂度是O(n), 即随着数据规模的增大而增加耗时.set,dict等结构,内部使用hash值作为key,时间复杂度可以做到O(1),查询时间与数据规模无关.
可hash:
数值型: int,float,complex.
布尔型: True,False.
字符串: string, bytes.
tuple.
None.
以上都是不可变类型,成为可哈希类型,hashable.
集合运算
基本概念:全集: 所有元素的集合.例如实数集,所有实数组成的集合就是全集.
子集(subset)和超集(superset): 集合A的所有元素在集合B中,A是B的子集,B是A的超集.
真子集和真超集: A是b的子集,且A不等于B,A就是B的真子集,B是A的真超集.
并集: 多个集合合并的结果.
交集: 多个集合的公共部分.
差集: 集合中除去和其他集合公共的部分.
并集:
union(*others) # 返回和多个集合合并后的新的集合.
"|"运算符重载: 等同于union.
update(*others): 和多个集合合并,就地修改.
"|=": 等同于update.
交集:
intersection(*others): 返回和多个集合的交集.
"&": 等同于intersection.
intersection_update(*others): 获取和多个集合的交集,并就地修改.
"&=": 等同于interse_update.
差集:
difference(*others): 返回和多个集合的差集.
"-": 等同于differenc.
difference_update(*others): 获取和多个集合的差集并就地修改.
"-=": 等同于difference_update.
对称差集:
symmetric_difference(other): 返回和另一个集合的差集.
"^": 等同于symmetric_difference.
symmetric_difference_update(other): 获取和另一个集合的差集并就地修改.
"^=": 等同于symmetric_difference_update.
issubset(other)和"<=": 判断当前集合是否是另一个集合的子集.
set1 < set2: 判断set1是否是set2的真子集.
issuperset(other)和">=": 判断当前集合是否是other的真超集.
set1 > set2: 判断set1是否是set的真超集.
isdisjoint(other): 判断当前集合和另一个集合有没有交集,没有交集返回True.
练习
字典 – dict
基本概念
key-value键值对的数据的集合.可变,无序,key不重复.
定义,初始化
d = dict()或者d = {}dict(**kwargs)使用name=value对初始化一个字典.
dict(iterable, **kwarg)使用可迭代对象和name=value对构造字典,不过可迭代对象的元素必须是一个二元结构.
d = dict(((1,'a'),(2,'b'))) or d = dict(([1,'a'],[2,'b']))
dict(mapping,**kwarg) 使用一个字典构建另一个字典.
d = {'a':10, 'b':20,'c':None,'d':[1,2,3]}
类方法 dict.fromkeys(iterable,value)
d = dict.fromkeys(range(5))
d = dict.fromkeys(range(5),0)
元素的访问
d[key]返回key对应的值value.
key不存在则抛出异常KeyError.
get(key[,default])
返回key对应的值value.
key不存在返回缺省值,如果没有缺省值就返回None.
setdefault(key[,default])
返回key对应的值value.
key不存在则添加kv对,value为default,缺省值为None.
增加和修改元素
d[key] = value将key对应的值修改为value.
key不存在则添加新的kv对.
update([other]) -> None
使用另一个字典的kv对更新本字典.
key不存在,就添加.
key存在,覆盖已存在的key对应的值.
就地修改.
123456789101112131415161718 | In [16]: d = {'a': 1, 'b': 2} In [17]: d.update(red=1) In [18]: d Out[18]: {'a': 1, 'b': 2, 'red': 1} In [19]: d.update((('red', 2),)) In [20]: d Out[20]: {'a': 1, 'b': 2, 'red': 2} In [21]: d.update({'red': 3}) In [22]: d Out[22]: {'a': 1, 'b': 2, 'red': 3} In [23]: |
1234567891011121314151617181920212223242526 | In [31]: d = (('red', 2)) In [32]: d Out[32]: ('red', 2) In [33]: dd = {'a': 1} In [34]: dd.update(d) --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-34-5fa4147f974f> in <module>() ----> 1 dd.update(d) ValueError: dictionary update sequence element #0 has length 3; 2 is required In [35]: d = (('red', 2),) In [36]: d Out[36]: (('red', 2),) In [37]: dd.update(d) In [38]: dd Out[38]: {'a': 1, 'red': 2} In [39]: |
删除元素
pop(key[,default]) key存在,移除它,并返回它的value.key不存在,返回给定的default.
default未设置,key不存在则抛异常KeyError.
popitem() 移除并返回一个任意的键值对.
字典为empty,抛出异常KeyError.
clear() 清空字典.
字典删除
del语句12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 | In [40]: a = True In [41]: b = [6] In [42]: d = {'a': 1, 'b': b, 'c': [1, 3, 5]} In [43]: d Out[43]: {'a': 1, 'b': [6], 'c': [1, 3, 5]} In [44]: del a In [45]: a --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-45-60b725f10c9c> in <module>() ----> 1 a NameError: name 'a' is not defined In [46]: del d['c'] In [47]: d Out[47]: {'a': 1, 'b': [6]} In [48]: del b[0] In [49]: b Out[49]: [] In [50]: c = b In [51]: del c In [52]: del b In [53]: c --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-53-2cd6ee2c70b0> in <module>() ----> 1 c NameError: name 'c' is not defined In [54]: b --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-54-3b5d5c371295> in <module>() ----> 1 b NameError: name 'b' is not defined In [55]: b = d['b'] In [56]: b Out[56]: [] |
字典遍历
for … in dict12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 | # 遍历key In [57]: d = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5} In [58]: for k in d: ...: print(k) ...: one two four three five In [59]: for k in d.keys(): ...: print(k) ...: one two four three five In [60]: # 遍历value In [60]: for k in d: ...: print(d[k]) ...: 1 2 4 3 5 In [61]: for k in d.keys(): ...: print(d.get(k)) ...: 1 2 4 3 5 In [62]: for v in d.values(): ...: print(v) ...: 1 2 4 3 5 In [63]: # 遍历item,即kv对 In [64]: for item in d.items(): ...: print(item) ...: ('one', 1) ('two', 2) ('four', 4) ('three', 3) ('five', 5) In [65]: for k,v in d.items(): ...: print(k,v) ...: one 1 two 2 four 4 three 3 five 5 In [66]: |
python3中,keys,values,items方法返回一个类似与生成器的可迭代对象,不会把函数的返回结果复制到内存中.
python2中,上面的方法会返回一个新的列表,占据新的内存空间.所以python2建议用iterkeys,itervalues,iteritems版本,返回一个迭代器,而不是一个copy.
字典的key
字典的key的要求和set的元素要求一致.hashable可哈希才能作为key.
d = {1:0}
1234567891011 | In [67]: d = {1: 0, 2.0: 3, 'abc': None,('hello', 'world', 'python'):'string', b'abc': '135'} In [68]: d Out[68]: {'abc': None, 1: 0, 2.0: 3, b'abc': '135', ('hello', 'world', 'python'): 'string'} In [69]: |
工厂函数-defaultdict
defaultdict是Python内建dict类的一个子类.用法: defaultdict(default_factory[,...]) --> dict with default factory. 第一个参数是default_factory,缺省是None,它提供一个初始化函数,可以是list,tuple,set和dict等. 它的其他功能与dict相同,当key不存在时,会调用这个工厂函数来生成key对应的value,即提供一个默认值,从而避免KeyError异常.
12345 | >>> d = defaultdict(list) #default_factory是列表名称 >>> d['eric'] #访问一个不存在的键 [] #添加并返回默认值(一个空列表) >>> d defaultdict(<class 'list'>, {'eric': []}) |
123456789101112131415 | from collections import defaultdict d1 = {} d2 = defaultdict(list) for k in 'abcde': for v in range(5): if k not in d1.keys(): d1[k] = [] d1[k].append(v) print(d1) for k in 'mnopq': for v in range(3): d2[k].append(v) print(d2) print(type(d2)) # <class 'collections.defaultdict'> |
123456 | from collections import defaultdict dic = defaultdict(set) for i in 'abcd': for j in range(1, 5): dic[i].add(j) print(dic) |
有序字典-OrderedDict
python中的字典是无序的,因为它是按照hash来存储的,但collections模块自带的子类OrderedDict则可以很好的解决这个问题.123456789101112131415161718192021222324252627 | # 使用OrderedDict前 In [1]: dic = {} In [2]: dic['b'] = 2 In [3]: dic['a']= 1 In [4]: dic['c'] = 3 In [5]: dic Out[5]: {'a': 1, 'b': 2, 'c': 3} # 使用OrderedDict方法 In [7]: from collections import OrderedDict In [8]: dicc = OrderedDict() In [9]: dicc['b'] = 2 In [10]: dicc['a'] = 1 In [11]: dicc['c'] = 3 In [12]: dicc Out[12]: OrderedDict([('b', 2), ('a', 1), ('c', 3)]) In [13]: |
有序字典可以记录元素插入的顺序,打印的时候也是按照这个顺序输出打印的.
3.6版本的python的字典就是记录key插入的顺序.
相关文章推荐
- Python中list、tuple、dict、set总结
- Python中(Dict和Set类型、函数、切片 、迭代 )
- Python list tuple dict set map小总结
- Java容器学习笔记(二) Set接口及其实现类的相关知识总结
- oc 知识总结四 (NSSet、NSMutableSet)
- list,tuple,dict,字符串常用知识总结
- Java【多线程知识总结(2)】调用setDaemon(true)变成后台线程
- set, list 和map知识总结
- Java容器学习笔记(二) Set接口及其实现类的相关知识总结
- python基础2(dict—set—函数—切片—迭代—列表range)
- Python基础知识- list ,tuple ,dict 和 set
- list, tuple, dict, set的用法总结
- Struts2的知识整理总结(三)—— 数据封装和类型转换
- 黑马程序员——OC基础学习(四)---封装,继承和多态的学习知识总结
- Java【多线程知识总结(2)】调用setDaemon(true)变成后台线程
- java知识总结(三)封装、继承和多态
- HashCode知识总结(以set存储对象为例进行说明)
- c++面向对象三大特征封装、继承和多态知识总结
- 一周知识总结(常用封装函数总结)
- Java【多线程知识总结(2)】调用setDaemon(true)变成后台线程