切片
在很多编程语言中,针对字符串提供了很多各种截取函数(例如,substring),其实目的就是对字符串切片。Python没有针对字符串的截取函数,只需要切片一个操作就可以完成,非常简单。
我们先创建一个0-99的数列:
>>>
L = list(range(
100
))
>>>
L[
0
,
1
,
2
,
3
, ...,
99
]
可以通过切片轻松取出某一段数列。比如前10个数:
>>>
L
[:10][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
后10个数:
>>>
L
[-10:][90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
前11-20个数:
>>>
L
[10:20][10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
前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]
甚至什么都不写,只写
[:]
就可以原样复制一个list:
>>>
L
[:][0, 1, 2, 3, ..., 99]
迭代
>>>
d = {
'a'
:
1
,
'b'
:
2
,
'c'
:
3
}
>>>
for
key
in
d:
...
print(key)...acb
dict迭代的是key。如果要迭代value,可以用
for value in d.values()
,如果要同时迭代key和value,可以用
for k, v in d.items()
。
当我们使用
for
循环时,只要作用于一个可迭代对象,
for
循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。
那么,
如何判断一个对象是可迭代对象
呢?方法是通过collections模块的Iterable类型判断:
>>>
from
collections
import
Iterable
>>>
isinstance(
'abc'
, Iterable)
# str是否可迭代
True
>>>
isinstance([
1
,
2
,
3
], Iterable)
# list是否可迭代
True
>>>
isinstance(
123
, Iterable)
# 整数是否可迭代
False
如果要对list实现类似Java那样的下标循环怎么办?Python内置的
enumerate
函数可以把一个list变成索引-元素对,这样就可以在
for
循环中同时迭代索引和元素本身:
>>>
for
i, value
in
enumerate([
'A'
,
'B'
,
'C'
]):
...
print(i, value)...
0
A
1
B
2
C
列表生成式
要生成
[1x1, 2x2, 3x3, ..., 10x10]
怎么做
>>>
L = []
>>>
for
x
in
range(
1
,
11
):
...
L.append(x * x)...
>>>
L[
1
,
4
,
9
,
16
,
25
,
36
,
49
,
64
,
81
,
100
]
----------------------------------------------------
>>>
[x * x
for
x
in
range(
1
,
11
)][
1
,
4
,
9
,
16
,
25
,
36
,
49
,
64
,
81
,
100
]
还可以使用两层循环,可以生成全排列:
>>>
[m + n
for
m
in
'ABC'
for
n
in
'XYZ'
][
'AX'
,
'AY'
,
'AZ'
,
'BX'
,
'BY'
,
'BZ'
,
'CX'
,
'CY'
,
'CZ'
]
写列表生成式时,把要生成的元素
x * x
放到前面,后面跟
for
循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
>>>
[x * x
for
x
in
range(
1
,
11
)
if
x %
2
==
0
][
4
,
16
,
36
,
64
,
100
]
生产器
通过列表生成式,我们可以直接创建一个
列表
。但是,
受到内存限制
,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不
必创建完整的list
,从而节省大量的空间。在Python中,
这种一边循环一边计算的机制,称为生成器:generator
。
要创建一个generator,有很多种方法。
第一种方法很简单,只要把一个列表生成式的
[]
改成
()
,就创建了一个generator:
>>
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
>
--------------------------------------------
第一种方法:如果一个函数定义中包含
yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator
def
fib
(max): n, a, b =
0
,
0
,
1
while
n < max:
yield
b a, b = b, a + b n = n +
1
return
'done'
迭代器
我们已经知道,可以直接作用于
for
循环的数据类型有以下几种:
一类是集合数据类型,如
list
、
tuple
、
dict
、
set
、
str
等;
一类是
generator
,包括生成器和带
yield
的generator function。
这些可以直接作用于
for
循环的对象统称为可迭代对象:
Iterable
。
可以使用
isinstance()
判断一个对象是否是
Iterable
对象:
>>>
from
collections
import
Iterable
>>>
isinstance([], Iterable)
True
在Python中,这种一边循环一边计算的机制,称为生成器:generator。
当循环完之后,生成器里面就没有了
因为她是一个推算方法,用完一次,就不能再用了 里面就空了
生产器都是Iterator
但是集合类型 list dict str 等虽然是Iterable的但是不是Iterator