您的位置:首页 > 其它

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,就地修改.

1234567891011121314151617181920In [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 .. in
len()可以获取长度.
通过下标可以访问.
可以切片.

学过的线性结构: list, tuple, str, bytes,bytearray.

切片

通过索引区间访问线性结构的一段数据.
sequence[start:stop] # 表示返回[start, stop)区间的子序列.
支持负索引.
start为0,可以省略.
stop为末尾,可以省略.
start一定在stop的左边.
[:]表示从头至尾,全部元素被取出,等效于copy()方法.
步长切片: [start:stop:step]
step为步长,可以是正负整数,默认为1. step要和start:stop同向,否则返回空序列.

12345678910111215161718In [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特有语法,被很多语言学习和借鉴.

1234567891011121314151617In [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
举例:

123456789101112131415161718192021222324252627In [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的解构

使用"*变量名"接收,但不能单独使用.
被"*变量名"收集后组成一个列表.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647In [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]:

丢弃变量

这是一个惯例,是一个不成文的约定,不是标准.
如果不关心一个变量,就可以定义修改变量的名字为下划线(_).
"_"是一个合法的标识符,也可以作为一个有效的变量使用,但是定义成下划线就是希望不要被使用,除非你明确的知道这个数据需要被使用.

12345678910111213141516In [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]:
1234567891011121314In [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可迭代.

12345678910111213141516171819202122232425262728In [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必须是可迭代对象.
就地修改.

1234567891011121314151617In [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()
移除所有元素.

12345678910111213141516171819202122232425262728293031In [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对应的值.
就地修改.

123456789101112131415161718In [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]:
1234567891011121314151617181920212223242526In [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语句

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455In [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 dict

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273# 遍历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}

1234567891011In [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': []})
123456789101112131415from 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'>

123456from 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插入的顺序.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bytes bytearray 切片