左康波

业余文艺cg场景模型师

Python系列(三)之高级特性

  |  
 阅读次数

切片操作(slice),即从list(tuple是一种特殊的list)中获取部分元素。

1. 切片

Contents
  1. 1. 1. 切片
  2. 2. 2. 迭代
    1. 2.1. 2.1 迭代的概念
    2. 2.2. 2.2 迭代的使用
      1. 2.2.1. 2.2.1 dict的迭代
      2. 2.2.2. 2.2.2 字符串的迭代
      3. 2.2.3. 2.2.3 迭代的索引
      4. 2.2.4. 2.2.4 多变量迭代
  3. 3. 3. 列表生成式
  4. 4. 4. 生成器
    1. 4.1. 4.1 直接创建generator
    2. 4.2. 4.2 通过函数方式创建
  5. 5. 5. 迭代器
    1. 5.1. 5.1 可迭代对象
    2. 5.2. 5.2 迭代器
  6. 6. 推荐文章

切片操作(slice),即从list(tuple是一种特殊的list)中获取部分元素。

  • L[m,n]表示从L[m]~L[n-1]的list。
  • L[:n]表示从L[0]~L[n-1]的list。
  • L[m:]表示从L[m]~L[len(L)-1]。
  • L[-m:]表示倒数m个数的list。
  • L[m:n:k]表示从L[m:n]list中每k个取一个数组成一个新的list。
  • L[::k]表示从L中每k个取一个组成新的list。
  • tuple也是一种list(不可变的list),使用切片操作的结果仍为tuple。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#定义list
>>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
#切片操作
>>> L[0:3]
['Michael', 'Sarah', 'Tracy']
>>> L[:3]
['Michael', 'Sarah', 'Tracy']
>>> L[1:3]
['Sarah', 'Tracy']
>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']

#定义0-99的list
>>> L = list(range(100))
#前10个数每两个取一个
>>> L[:10:2]
[0, 2, 4, 6, 8]
#所有数,每5个取一个
>>> L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]

#tuple的切片操作
>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)

#字符串切片操作
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'

2. 迭代

2.1 迭代的概念

迭代:在某类对象的集合中通过遍历的方法来获取元素,对元素执行某项操作。

Python中的可迭代对象有:list,tuple,dict,str等,包括可迭代的自定义类型。

判断一类对象是否可迭代,可以通过collections模块的Iterable类型判断。例如:

1
2
3
4
5
6
7
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False

2.2 迭代的使用

在Python中,迭代是通过for ... in来完成的。

2.2.1 dict的迭代

1
2
3
4
5
6
7
>>> d = {'a': 1, 'b': 2, 'c': 3}
>>> for key in d:
... print(key)
...
a
c
b
  • dict默认迭代的是key,for key in d
  • 可以使用for value in d.values()来迭代value。
  • 可以用for k, v in d.items()来迭代key和value。

2.2.2 字符串的迭代

1
2
3
4
5
6
>>> for ch in 'ABC':
... print(ch)
...
A
B
C

2.2.3 迭代的索引

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身。

1
2
3
4
5
6
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C

2.2.4 多变量迭代

在for中,同时引用多个变量。例如:

1
2
3
4
5
6
>>> for x, y in [(1, 1), (2, 4), (3, 9)]:
... print(x, y)
...
1 1
2 4
3 9

3. 列表生成式

列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。

一般是通过for … inrange来生成list。

1
2
3
4
5
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

for循环中加if判断

1
2
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

多层循环

1
2
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

多变量循环

1
2
3
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']

可以使用内建的isinstance函数可以判断一个变量是不是字符串。

4. 生成器

在Python中,一边循环一边计算的机制,称为生成器:generator。生成器不必创建完整的list,可以在循环中不断推算出后续的元素,从而可以在获取所需元素的同时节省存储空间。

4.1 直接创建generator

创建generator即把列表生成式的[]改成()

1
2
3
4
5
6
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>

一般通过for循环来获取generator的元素,也可以使用next(g)来获取下一个元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> g = (x * x for x in range(10))
#通过for循环获取元素
>>> for n in g:
... print(n)
...
0
1
4
#通过next()获取元素
>>> next(g)
0
>>> next(g)
1

4.2 通过函数方式创建

通过yield关键字将一个函数变成generator。例如:

函数的定义:

1
2
3
4
5
6
7
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'

生成器的定义:

1
2
3
4
5
6
7
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'

两者的差别在于生成器将函数的print(b)改为yield byield可以翻译为生成,即基于某次计算生成某个元素,而不是提前存储了该元素。

函数式的generator一般采用for循环来获取元素,也可以通过next()来获取下一个元素的值,例如:

1
2
3
4
5
6
7
8
9
>>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8

如果要获取return的内容,可以捕获StopIteration错误,返回值包含在StopIterationvalue中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done

5. 迭代器

5.1 可迭代对象

可以直接作用于for循环的对象统称为可迭代对象:Iterable。主要有:

  • 集合数据类型,如listtupledictsetstr
  • generator,包括生成器和带yield的generator function

可以使用isinstance()判断一个对象是否是Iterable对象:

1
2
3
4
5
6
7
8
9
10
11
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

5.2 迭代器

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

生成器都是Iterator对象,但listdictstrIterable,而不是Iterator

可以使用isinstance()判断一个对象是否是Iterator对象:

1
2
3
4
5
6
7
8
9
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

可以通过iter()函数将Iterable转换成Iterator

1
2
3
4
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

Python的Iterator对象表示的是一个数据流,可以是无限大的数据流,例如全体自然数。

  • Iterator的元素是基于计算的,可以理解为惰性的、动态的、长度未知的(元素个数可能无限)。
  • listdictstr的元素是基于存储的,可以理解为静态的、长度已知的(元素个数有限)。

隐藏