python惰性求值有哪些函数

Python022

python惰性求值有哪些函数,第1张

Copyright © 1999-2020, CSDN.NET, All Rights Reserved

惰性计算的序列

打开APP

Python 的惰性求值与惰性序列 翻译

2018-07-23 14:57:48

2点赞

东师小镇

码龄5年

关注

惰性求值

在编程语言理论中,惰性求值(英语:Lazy Evaluation),又译为惰性计算、懒惰求值,也称为传需求调用(call-by-need),是一个计算机编程中的一个概念,它的目的是要最小化计算机要做的工作。它有两个相关而又有区别的含意,可以表示为“延迟求值”和“最小化求值”。

避免不必要的计算,带来性能的提升(最小化求值)。

对于Python中的条件表达式 if x and y,在x为false的情况下y表达式的值将不再计算。而对于if x or y,当x的值为true的时候将直接返回,不再计算y的值。因此编程中可以利用该特性,在 and逻辑中,将小概率发生的条件放在前面或者在or逻辑中,将大概率发生的时间放在前面,有助于性能的提升。

2. 节省空间,使得无线循环的数据结构成为可能(延迟求值)。

延迟求值特别用于函数式编程语言中。在使用延迟求值的时候,表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值。延迟求值的一个好处是能够建立可计算的无限列表而没有妨碍计算的无限循环或大小问题。例如,可以建立生成无限斐波那契数列表的函数(经常叫做“流”)。第n个斐波那契数的计算仅是从这个无限列表上提取出这个元素,它只要求计算这个列表的前n个成员。

惰性序列

Python的惰性序列多数指 iterator,其特点正如同上文所述,具有惰性计算特点的序列称为惰性序列。

Python的iterator是一个惰性序列,意思是表达式和变量绑定后不会立即进行求值,而是当你用到其中某些元素的时候才去求某元素对的值。 惰性是指,你不主动去遍历它,就不会计算其中元素的值。

一句话理解:

迭代器的一个优点就是它不要求你事先准备好整个迭代过程中所有的元素。

迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。

这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。

可以通过eval()函数来求值

例如:

x = 10

y = 20

formula = 'x*y+10-(x-y)'

result = eval(formula)

print(result)

和很多高级编程语言一样,Python默认参数也有很大的用处。但是我们在使用的时候会出现不少的问题,这些问题就需要我们用相关的知识进行解答。当默认参数是数值类型时,一切都很美好:

>>>def function(a, b = 1000000):

b +=a

return b 如果你喜欢,你可以在一段代码中无数次的调用这个函数,只要你参数一样,结果应该都一样。比如:function(1)总是会返回1000001。但是默认参数是其他类型(如列表)时就没那么美好了:

>>>def function(a, b = []):

b.append(a)

print(b)

这时你如果在一段代码中持续的调用该函数,将会发生或许令人意外的情况:第一次调用function(1)的时候,很正常,会打印出[1],但是第二次再调用function(1),将会打印出[1,1]。这是为什么呢?不要紧,使用Python默认参数我们有办法检查一下是哪里出了毛病。这里我们可以在每一次调用函数的时候打印出b的ID。Python中一个对象的ID在其生命周期中是唯一的,和其他高级语言中所说的对象的地址一样。如果第二段代码中的b对象其ID一样,说明两次调用都使用的同一个对象,换句话说,Python默认参数的求值操作在其生命周期中只发生一次(第一次)。可以使用以下的代码测试我们的想法:

def function1(a,b=100000):

b+=a

print("b = {0} with the id of {1}".format(b,id(b)))

def function2(a,b=[]):

b.append(a)

print("b = {0} with the id of {1}".format(b,id(b)))

def test():

function1(1)

function1(1)

function2(1)

function2(1)

if __name__ == '__main__':

test()

得到的输出如下:

b = 100001 with the id of 33384304

b = 100001 with the id of 33384304

b = [1] with the id of 33341848

b = [1, 1] with the id of 33341848

以上就是对Python默认参数的详细介绍。果然,从后面两条结果中可以看到列表b在两次调用时都是使用的同一个对象,看来之前的猜想是正确的。对非数值类型的默认参数,只会在第一次调用时进行求值(取地址)操作。后面的所有调用都发生在同一个位置的对象上。只有字符串类型不受此限制,因为string本身是不可变的(immutable)的,每一次修改它都会创建一个新的对象。