lambda使用方法如下:
lambda [arg1 [,arg2,.....argn]]: Exp
例如:
sum = lambda x, y: x+y
s1 = sum(2,3)
print("Sum is:", s1)
结果为:
('Sum is:', 5)
lambda与C/C++中内联函数的区别:
C/C++中的内联函数是为了调用小函数时不占用栈内存从而增加运行效率。
而lambda并不提高效率,只是为了使得代码简练清晰。
1.2.2.:与filter, map, reduce组合使用:
Python提供了几个函数方便用户使用---filter, map, reduce。他们支持把函数作为参数。
filter:
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或
False,最后将返回 True 的元素放到新列表中。
所以可以使用lambda创建一个匿_名函数,作为filter的第一个参数。
参数
function -- 判断函数。
iterable -- 可迭代对象。
返回值
返回一个迭代器对象(Python3)
Python2中,则返回列表。
Python2:
old_v = [1,2,3,4,5,6,7,8]
new_v = filter(lambda x:x % 2 == 0, old_v)
print(new_v)
结果:
[2, 4, 6, 8]
map():
描述
map() 会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function
函数返回值的新列表。
语法
map() 函数语法:
map(function, iterable, ...)
参数
function -- 函数
iterable -- 一个或多个序列
返回值
Python 2.x 返回列表。
Python 3.x 返回迭代器。
例:
old_v = [1,2,3,4,5,6,7,8]
plus_v = [2,3,4,5,6,7,8,9]
plus_new = map(lambda x, y: x+y, old_v, plus_v)
print(plus_new)
结果:
[3, 5, 7, 9, 11, 13, 15, 17]
reduce()
描述
reduce() 函数会对参数序列中元素进行累积。
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数
function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function
函数运算,最后得到一个结果。
语法
reduce() 函数语法:
reduce(function, iterable[, initializer])
参数
function -- 函数,有两个参数
iterable -- 可迭代对象
initializer -- 可选,初始参数
返回值
返回函数计算结果。
2. 迭代器和生成器:
2.1:迭代器(iterator):
迭代是Python最强大的功能之一。是访问集合元素的一种方式。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完而结束。 迭代器只能前进不能后退。
迭代器有两个基本方法: iter(), next()
iter()用来创建迭代器对象。它返回一个特殊的迭代器对象,这个对象实现了next()方法。
next()逐一返回迭代器对象中的元素。当没有数据可用时,会引发:StopIteration异常。
利用迭代器对象,可是使用for....in方式逐个访问集合内元素。
字符串,元祖(tuple)或者列表(List)对象都可以用于创建迭代器。文件对象(相当于文件描述符)也可以用来创建迭代器--文件迭代器。(见注1:可迭代对象),
例1:List, tuple, 字符串对象用来创建迭代器。
#List
list1 = [1,2,3,4,5,"sam", "test"]
it = iter(list1)
print("Iter1",next(it))
for i in it:
print(i)
注意:it是一个迭代器,可以通过next(it)和for 去取下一个元素。 但它只能从前往后取。
所以第一个next(it)取出一个元素后。 for则从下一个开始取。
#Tuple
tuple1 = ("t1", "t2", 9,8,7)
it = iter(tuple1)
print("Iter2")
for i in it:
print(i)
#String
var1 = "Hello World!"
it = iter(var1)
print("Iter3:")
for i in it:
print(i)
Iter3:
H
e
l
l
o
W
o
r
l
d
!
#文件迭代器
逐行显示文件内容。
for i in open("test.txt",
encoding="utf-8"):
print(i)
也可以自定义迭代器。
例:
2.2: 生成器(generator):
生成器是个函数,与普通函数不同的是,它返回一个迭代器。
生成器的表示是使用yield.
在调用生成器过程中,每次遇到yield时,函数会暂停并保存当前所有运行信息,返回yield的值,并在下一次调用时从当前位置继续执行。
def
fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if
(counter > n):
return
yield
a
a, b = b,
a + b
counter +=
1
f =
fibonacci(10) # f 是一个迭代器,由生成器返回生成
for i in
f:
print(i)
3. 文件夹的遍历:
dirnames:是个list. 内容是dirpath目录内所有目录名(不包括子目录,不包括 . 和 ..)
因为是个迭代器, 所以可以用 for.....in ....
返回一个list. 包含目录path内左右文件名(包括目录名)。
问题一:既然可迭代对象也可以使用for循环遍历,为何还要使用迭代器呢?
一般情况下不需要将可迭代对象封装为迭代器。但是想象一种需要重复迭代的场景,在一个class中我们需要对输入数组进行正序、反序、正序step=1、正序step=2等等等等的多种重复遍历,那么我们完全可以针对每一种遍历方式写一个迭代容器,这样就不用每次需要遍历时都费劲心思的写一堆对应的for循环代码,只要调用相应名称的迭代器就能做到,针对每一种迭代器我们还可以加上类型判断及相应的处理,这使得我们可以不必关注底层的迭代代码实现。
从这种角度来看,你可以将迭代器看做可迭代对象的函数化,有一个非常流行的迭代器库itertools,其实就是如上所说的,他为很多可迭代类型提前定义好了一些列的常见迭代方式,并封装为了迭代器,这样大家就可以很方便的直接通过调用此模块玩转迭代。
此外iterator还可以节省内存,这点在问题二会描述。
问题二:生成器(generator)如何节约内存的?
generator的标志性关键字yield其实可以看作return,以本文上述的generator_list()方法为例,generator_list(a)就是一个生成器。
生成器最大的好处在于:generator_list(a)并不会真正执行函数的代码,只有在被循环时才会去获取值,且每次循环都return一个值(即yield一个值),在处理完毕后下次循环时依然使用相同的内存(假设处理单位大小一样)来获取值并处理,这样在一次for循环中函数好像中断(yield)了无数次,每次都用相同大小的内存来存储被迭代的值。
yield与return的最大区别就是yield并不意味着函数的终止,而是意味着函数的一次中断,在未被迭代完毕之前yield意味着先返回一次迭代值并继续下一次函数的执行(起始位置是上一次yeild语句结束),而return则基本意味着一个函数的彻底终止并返回一个全量的返回值。
因此generator是为了节省内存的,而且将函数写为一个生成器可以使函数变的可迭代,如果我们想遍历函数的返回值,我们不用再单独定义一个可迭代变量存储函数的返回值们,而是直接迭代生成器函数即可(除非函数本身返回一个全量的可迭代对象)。
同理iterator的__iter__()方法只是一个迭代的入口,每次调用__next__()时返回一个迭代值,同样以O(1)的空间复杂度完成了迭代。
问题三:iterator与generator的异同?
generator是iterator的一个子集,iterator也有节约内存的功效,generator也可以定制不同的迭代方式。