1.切片
用来取list或者tuple元素:
L[0:3]; #取得前三
L[:3]; #取得前三
L[-10:]; #取得后十
2.迭代
如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)。
for key in d: #获取所有元素
3.列表生成式
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
>>> [m + n for m in 'ABC' for n in 'XYZ'] #典型的两次循环生成列表
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
4.生成器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]
改成()
,就创建了一个generator:
>>> g = (x * x for x in range(10)) #典型的生成器定义
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
自定义生成器,在每次调用
next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。
def odd():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o) #执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错
Traceback (most recent call last):
File "", line 1, in
StopIteration
5.迭代器
列表、元组、字典等可以迭代,但只有元组是迭代对象。生成器(generator)与List之类的集合数据类型同为可迭代对象,但生成器内部储存的是算法,可以由next()函数得到下一次计算的返回值,满足迭代器的特点;而list之类的集合数据类型内部储存的
>>> 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
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
1.高阶函数
(1)map/reduce
map
map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
>>> def f(x):
... return x * x
...
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
典型的map()生成列表:
>>> list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']
reduce
reduce把一个函数作用在一个序列[x1, x2, x3, ...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])
13579
总结:map单独处理每一个结果,reduce把前一次处理的结果与下一次参数一起进行再次运算。
(2)filter
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])) #可见本质上filter是个筛选函数
# 结果: ['A', 'B', 'C']
(3)sorted
Python内置的sorted()函数就可以对list进行排序:
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
可以给sorted的key参数进行修改,按照成绩排序:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
def by_name(t):
return t[0]
L2 = sorted(L, key=by_name)
print(L2)
2.返回函数与闭包
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum #返回的是一个函数
>>> f = lazy_sum(1, 3, 5, 7, 9)
>>> f
.sum at 0x101c6ed90>
>>> f()
25
在这个例子中,我们在函数lazy_sum中又定义了函数sum,并且,内部函数sum可以引用外部函数lazy_sum的参数和局部变量,当lazy_sum返回函数sum时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构拥有极大的威力。
3.匿名函数
>>> list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[1, 4, 9, 16, 25, 36, 49, 64, 81]
通过对比可以看出,匿名函数lambda x: x * x实际上就是:
def f(x):
return x * x
关键字lambda表示匿名函数,冒号前面的x表示函数参数。
4.装饰器
一个典型的装饰器:
def log(func):
def wrapper(*args, **kw): #参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2015-3-25')
>>> now()
call now():
2015-3-25
假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。(这里就不展示多层嵌套的例子)
5.偏函数
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
>>> import functools
>>> int2 = functools.partial(int, base=2) #构造一个简单的函数
>>> int2('1000000')
64
>>> int2('1010101')
85
参考网站:廖雪峰的官方网站