HOME
HOME
文章目录
  1. 1. 字符串与字节
  2. 2. 集合类型

python进阶之基础类型

python一直在使用,但不太深入,现正好深入学习一下,参考的书籍是《python高级编程第2版》、《流畅的python》。这两本书一直想抽空读一遍,最近得空深入学习一下。后面一系列文档均是这些书的学习笔记。

1. 字符串与字节

python3中所有的字符串均为unicode文本。即所有的字符串为str对象,str对象均由unicode字符组成。

而所有的字节对象前面需要加上b,表示该串字符序列为bytes

编码与解码

以前在进行字符串与字节码转换时,经常搞不清楚到底该用encode还是decode。为方便记忆,我们可以将字节序列当成机器可读的存储字节,字符串想成人类可读的抽象的文本。把难读懂的机器码转换成抽象文本就是解码,将抽象文本换成机器存储的字节就是编码

解码有两种方式:

  • 使用str.decode(encoding, errors)方法,对字节进行解码。encoding默认值为utf-8
  • 使用str(source, encoding, errors)函数对字节码进行解码,创造一个新的字符串。

编码的方式也同样有两种:

  • 使用str.encode(encoding, errors)方法,对字节进行编码。encoding默认值为utf-8
  • 使用bytes(source, encoding, errors)函数对字符串进行编码。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
>>> s = '∑çewqe'
>>> len(s)
6
>>> b = s.encode('utf8')
>>> len(b)
9
>>> print(b)
b'\xe2\x88\x91\xc3\xa7ewqe'
>>> type(b)
<class 'bytes'>
>>> type(s)
<class 'str'>

不可变字符串及字节序列

python的字符串是不可变的,字节序列也是不可变的。每当需要修改字符串时,生成的均是一个全新的字符串。

使用+拼接字符串生成的是一个新的字符串,可参考如下代码:

1
2
3
4
5
6
7
8
>>> s = "test"
>>> id(s)
4430539696
>>> s = s + 'me'
>>> print(s)
testme
>>> id(s)
4429430640

针对于字符串的拼接,如果用+在python中的速度会非常慢,所以python提供了一个str.join()方法。可以使用这个方法提高字符串拼接的速度,也可以在字符串之间更容易的插入分隔符

1
2
3
4
5
6
7
>>> s = "testme"
>>> s = "".join(['test', s])
>>> print(s)
testtestme
>>> s = ",".join(['test', s])
>>> print(s)
test,testtestme

2. 集合类型

python的集合类型一共包含以下几种类型:

  • 列表(list)
  • 元组(tuple)
  • 字段(dict)
  • 集合(set)

一般在工作中使用频率最高的还是列表和字段,set类型用于数据去重的时候,最为方便。

元组(tuple)

元组是不可变的,也是可哈希的。元组没有太多细节可说,一般用来存放不需要变化的数据,例如坐标。

列表(list)

list是一个可变序列,每个节点可以存放不同类型的元素。list中最为重要的一个概念就是列表推导式,是构成一个列表的最快捷的方法。

列表推导式

列表推导式可以直接使用列表的格式生成需要的列表,例如:

1
2
3
>>> s = [x for x in range(0,10) if x % 2 == 0]
>>> print(s)
[0, 2, 4, 6, 8]

在循环获取列表的时候,如果要获取列表下标可以采用以下的方法:

1
2
3
4
5
6
7
>>> for index, value in enumerate([1,2,3,4]):
... print(index,value)
...
0 1
1 2
2 3
3 4

字典

字典也能进行字典推导式

1
2
3
4
5
6
s = {num: num for num in range(0,5)}

print(s)

# output:
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}

在python3中,遍历字典返回的 keys()、values()、items()不再是列表,返回的是视图对象。

  • keys():返回dict_keys对象,可查看字典的所有键
  • values():返回dict_values对象,可查看字典所有值
  • items(): 返回dict_item对象,可查看所有的(key, value)二元元组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
s = {'1': 'test', '2': 'test2'}

print(s.keys())
print(s.values())
print(s.items())

for i in s.keys():
print(i)

# output
dict_keys(['1', '2'])
dict_values(['test', 'test2'])
dict_items([('1', 'test'), ('2', 'test2')])
1
2

集合

set()是一种可变的、无序的、有限的集合,元素是唯一的,不可变的对象。

frozenset()是一种不可变的、无序的集合,元素是唯一的,不可变的对象。

集合也存在集合推导:

1
2
3
4
5
6
7
s = {x for x in range(10)}
print(type(s))
print(s)

# output
<class 'set'>
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

collection模块

该模块是日常使用中作为基础类型的补充,也是使用比较频繁的数据结构。

常用的类型有:

  • 计数器(counter)
  • 双向队列(deque)
  • 默认字典(defaultdict)
  • 有序字典(OrderedDict)
  • 具名元组(namedtuple)

namedtuple

主要用于定义一个简单的不变集合。如果使用类定义的话,显得太过臃肿。

例如可以定义一个点:

1
2
3
4
5
6
7
8
9
10
11
12
p = (1, 2)  # 不太好明白意思

from collections import namedtuple


Point = namedtuple('Point', ['x', 'y'])
p = Point(1, 2)
>>> p.x
1
>>> p.y
2

deque

list是常用的列表,循环遍历的时候很快,但数据量太大了之后,插入和删除效率会非常低。所以python提供了deque类型,双向列表。

deque可以实现非常高效的插入和删除操作,适用于队列和栈的数据类型。

deque默认的是栈的数据结构,使用最简单的pop是弹出队列末尾的数据,也就是先进后出,后进先出的栈的模式。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> from collections import deque
>>> q = deque([1,2,3,4,5])
>>> q.pop()
5
>>> q.pop()
4
>>> q.append(1)
>>> q
deque([1, 2, 3, 1])
>>> q.popleft()
1
>>> q
deque([2, 3, 1])

defaultdict

使用dict如果key不存在会抛出KeyError的错误。而defaultdic就是解决这个问题的,在key不存在时,会返回一个默认值。

1
2
3
4
>>> from collections import defaultdict
>>> d = defaultdict(lambda: 'None')
>>> d['xxx']
'None'

另外两种数据结构也类似,用到的时候再查文档吧。