Python-函数其他
切片
对于list和tuple来说,可能有事需要获得他们的子串,而Java等都提供了类似subString()
的方法来获取子串,而对于Python来说则有一种方法叫 切片
例如:
L = ['michel','Sarah','Bob','Tom']
想要获取L的前2个元素怎么办?
当然也可以使用for
循环,但是这样太麻烦了。
>>>L[0:3]
['michel','Sarah','Bob']
这样既可获得前2个元素,L[0:3]
表示从下标0
开始(包括0
),3
结束(不包括3
)。
如果是从0
开始的话,0
可以省略,即 L[:3]
因为下标 -1
可以访问最后一个元素,所以负数的下标也是可以的。
但是必须是第一个下标小于第二个下标,(包括第一个下标,不包括第二个下标)并且为正序输出的
>>>L[-3:-1]
['michel','Sarah']
L[-3:-1]
表示取 L
中的倒数第三个(包括)到倒数第一个(不包括)
迭代
就是遍历List或者tuple,在Java中多是for
来完成的
在Python中,使用 for...in
,它可以用在list,tuple,dict等上,例如在dict上:
>>>dic = {'x':1,'y':2,'z':3}
>>.for key in dic
··· print(key)
···
x
y
z
dict默认迭代的是key,如果迭代value,for value in dic.values()
,都遍历使用for key,value in d.items()
注意:dict内的顺序不一定,遍历多次的结果可能不一致
如何检查一个对象是不是可迭代对象呢?
通过collections模块的Iterable类型
>>>from collections import Iterable
>>>isinstance('abc',Interable)
True
列表生成式
用来快速生成list,例如要生成1*1,2*2,3*3,4*4,5*5,6*6
,我们怎么做?可以使用循环,但是过于麻烦
还可以使用
>>> l = [x * x for x in range(1,7) ]
>>> l
[1, 4, 9, 16, 25, 36]
for
循环之后还可以加上if
表达式,来筛选某些数
>>> l = [x * x for x in range(1,7) if x % 2 == 0]
>>> l
[4, 16, 36]
还可以使用两层循环来生成全排列
>>> l = [m + n for m in 'xyz' for n in 'abc']
>>> l
['xa', 'xb', 'xc', 'ya', 'yb', 'yc', 'za', 'zb', 'zc']
也可以利用一些方法来改变大小写
>>> l = ['Abc','Def','Ghi']
>>> [s.lower() for s in l]
['abc', 'def', 'ghi']
生成器
通过列表生成器我们可以生成一个list,但是收到内存限制,列表的大小肯定会有限制。
Python中有一个机制能够节省空间,条件是这个列表中的元素能够能够按照某种算法推导出来,然后只在使用的过程中推断出要使用的后序的元素,这被称为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 0x000002253945DAF0>
我们可以直接答应list
里面的全部元素,但是我们要怎么打印generator
里的元素呢?
使用next()
来访问下一个元素,当到最后一个元素之后没有更多元素时,会答应StopIteration
错误
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
当然一直调用next()
多余麻烦,也可以使用for
循环
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81
在原教程中的斐波那契数列的例子中,
def fib(max):
n, a, b = 0, 0, 1
while n < max:
print(b)
a, b = b, a + b
n = n + 1
return 'done'
提到了一个语句:a, b = b, a + b
这个语句的实际执行相当于:
t = (b, a + b) # t是一个tuple
a = t[0] #即a = b
b = t[1] #b = a + b !但是此时的a并没有赋值为b!!!!
关于以上的这个斐波那契数列函数,实际上也是一个一个一个推算的函数,对于这个函数,其实也可以变成generator
的,只需要将print(b)
改为yield b
就可以。
如果一个函数定义中包含yield
关键字,那么这个函数就不再是一个普通函数,而是一个generator
:
这里问题就在于 generator
函数的执行:在每次执行next()
的时候执行一次,遇到yield
就返回,下一次在上次返回的yield
的位置继续执行,例如:
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5
在调用时要先生成一个odd
函数,在调用next()
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
当然还可以用for
。
迭代器
以直接作用于for循环的对象统称为可迭代对象:Iterable
。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
- 凡是可作用于
for
循环的对象都是Iterable
类型; - 凡是可作用于
next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列; - 集合数据类型如
list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。 - Python的
for
循环本质上就是通过不断调用next()
函数实现的