资讯专栏INFORMATION COLUMN

python面试题之“该死的for循环系列”(一)

wudengzan / 2251人阅读

摘要:这是一道魔性面试题,难倒了无数英雄好汉上面代码的执行顺序是这样的从上到下第一个函数就是实现了一个简单的加法运算第二个函数是一个生成器函数,如果调用它会返回一个生成器这一行调用了生成器函数,所以此刻就是一个生成器它的本质还是迭代器然后执行循环

这是一道魔性面试题,难倒了无数英雄好汉……
def add(n,i):
    return n+i

def test():
    for i in range(4):
        yield i

g=test()
for n in [1,10]:
    g=(add(n,i) for i in g)
print(n)
print(list(g))
10
[20, 21, 22, 23]
上面代码的执行顺序是这样的:从上到下:
第一个函数add就是实现了一个简单的加法运算
第二个函数test是一个生成器函数,如果调用它会返回一个生成器
g=test(),这一行调用了生成器函数,所以此刻g就是一个生成器(它的本质还是迭代器)
然后执行for循环,这里迷惑人的就是这个for循环,为了减少它的魔性,我们把for循环拆开来看:
    当n = 1时:
    执行了:g=(add(n,i) for i in g)
    当n = 10时:
    执行了:g=(add(n,i) for i in g)
    

乍一看这两行代码还是有点迷糊,但是我们要知道,生成器有个最大的特性就是惰性,当你不进行迭代时它就不进行运算,想要对生成器进行迭代有以下几种方法:
第一种:for循环,for循环的本质就是调用了iter和next方法进行了迭代
第二种:调用next方法
第三种:调用send方法
第四种:数据类型强制转换,比如使用list()强制转换。
只要没有以上四种方法进行迭代,那么生成器就没有进行运算,所以在上面的for循环中无论是n=1时还是n=10时,生成器 g 都没有参与运算,

当n = 1时,g=(add(n,i) for i in g),这个表达式的结果g 就是一个表达式,没有进行运算,g的值就是一个表达式(add(n,i) for i in g),括号里面的g实际上是test(),所以g = (add(n,i) for i in test()),仅此而已
当n = 10时,g=(add(n,i) for i in g),把n=1时的g的结果带入进去就是g=(add(n,i) for i in (add(n,i) for i in test()))

当整段代码执行到print(list(g))语句之前,g的值就是一段代码,或者你可以称之为算法,没有进行任何运算,里面的n就是n,g就是g
不过此时因为代码是按照流程执行的,并且for循环已经执行完毕,所以n的值等于10

当执行print(list(g))语句时,生成器才开始输出数据,此时执行最后一个g的赋值语句:
g=(add(n,i) for i in (add(n,i) for i in test()))
这时 n 的值等于10(因为代码是按照流程执行的,for循环已经执行完了,n的最终结果就是10),其中后面的(add(n,i) for i in test())这段代码的结果依然是个生成器,迭代后应为[10,11,12,13],所以最终的结果可以理解成:(add(n,i) for i in [10,11,12,13]),所以最终结果为:20,21,22,23

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42559.html

相关文章

  • python面试题之该死for循环系列”(二)

    摘要:到这里,如果你明白了,我们就可以继续进行下一步了理解匿名函数。 似乎只要一沾上for循环,难度立刻加倍,下面我们来看一道python的面试题: 要求写出下面代码的输出结果并且解释原因。 def multipliers(): return [lambda x:i*x for i in range(4)] print([m(2) for m in multipliers()]) 这...

    shiweifu 评论0 收藏0
  • 数据分析面试题之Pandas中groupby

    摘要:昨天晚上,笔者有幸参加了一场面试,有一个环节就是现场编程题目如下示例数据如下,求每名学生对应的成绩最高的那门科目与,用实现这个题目看上去很简单,其实,并不简单。   昨天晚上,笔者有幸参加了一场面试,有一个环节就是现场编程!题目如下:  示例数据如下,求每名学生(ID)对应的成绩(score)最高的那门科目(class)与ID,用Python实现: showImg(https://se...

    ThinkSNS 评论0 收藏0
  • 用9种办法解决 JS 闭包经典面试题之 for 循环取 i

    摘要:闭包正确的说应该是指一个闭包域每当声明了一个函数它就产生了一个闭包域可以解释为每个函数都有自己的函数栈每个闭包域对象都有一个不是属性内默认有个名为的全局引用有了这个引用就可以直接调用的属性或方法凡是在闭包域内声明的变量或方法外部无法直接访问 闭包 正确的说,应该是指一个闭包域,每当声明了一个函数,它就产生了一个闭包域(可以解释为每个函数都有自己的函数栈),每个闭包域(Function...

    Betta 评论0 收藏0
  • 经典面试题之“a==1 && a==2 && a==3 为true”

    摘要:所以能用的地方尽量用,相等运算符隐藏的类型转换,会带来一些违反直觉的结果。 这是在国外的一道面试题看到的,大家先自己想一下,在什么情况下这个判断会成立?按正常思维想,这个是不可能成立的,但nothing is impossible,首先贴上正确答案代码 const a = { i: 1, toString: function () { return a.i++; }...

    Bryan 评论0 收藏0
  • JS面试题之比较两个对象是否相等?

    摘要:这是我在一次面试中,被面试官所提问的一道题在这次面试题中相等指的是对象的属性个数值相等有这样两个李德华张德华我能想到的一种方案解答过程的思考由于没有,我只能通过转化成数组进入第二步,对象中的属性在另一个中是否存在。 这是我在一次面试中,被面试官所提问的一道题 在这次面试题中 相等:指的是对象的属性个数值相等 有这样两个obj let obj1 = { name:李德华, ...

    wangbjun 评论0 收藏0

发表评论

0条评论

wudengzan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<