• python推导式特殊用法


    字典推导式

    >>> dic = {x: x**2 for x in (2, 4, 6)}
    >>> dic
    {2: 4, 4: 16, 6: 36}
    >>> type(dic)
    <class 'dict'>
    

    集合推导式

    >>> a = {x for x in 'abracadabra' if x not in 'abc'}
    >>> a
    {'d', 'r'}
    >>> type(a)
    <class 'set'>
    

    元组推导式

    圆括号在Python中被用作生成器的语法了,没有元组推导式。要通过类似方法生成元组,需要显式调用元组的类型转换函数tuple(),如下所示:

    tup = tuple(x for x in range(9))
    print(tup)
    print(type(tup))
    
    ------------------------
    结果:
    (0, 1, 2, 3, 4, 5, 6, 7, 8)
    <class 'tuple'>
    

    面试真题

    result = [lambda x: x + i for i in range(10)]
    print(result[0](10))
    

    这是一个结合了变量作用域、列表推导式和匿名函数的题目,其实答案是19,并且result0~9的结果都是19。

    这是因为函数具有调用时才查找变量的特性。在你没调用它之前,它不会保存也不关心它内部变量的具体值。只有等到你调用它的时候,它才逐一去找这些变量的具体值。这里的result[0]被调用的时候,变量i已经循环完毕,变成9了,而不是想象中的动态0-9值。

    使用debug查看的话,最后显示的是 x=10,i=9 最终结果是19

    分析:
    在列表生成式内定义的lambda函数是一个闭包,而变量i属于这个闭包引用的外部列表生成式中的变量。因此,在lambda函数内的i并不会被立即求值,而是会被保留为引用,直到调用这个lambda函数时,才去获取i的值。在列表生成式结束后,因为range(10)的关系i的当前值为9,也就是说生成的列表中每个lambda函数都是lambda x: x + 9,而不是一般所想象的lambda x: x+0, lambda x: x+1, ..., lambda x: x+9。因此,将10作为参数传递进无论哪个lambda函数,得到的结果都是10+9=19。

    那如果不想要这样的结果,想要i是循环的值怎么办?不要直接引用上层变量,把变量直接传进来。这样一来结果是10

    result = [lambda x, i=i: x + i for i in range(10)]
    print(result[0](10))
    
  • 相关阅读:
    小程序锚点使用过程
    小程序的生命周期
    微信小程序npm找不到npm包,没有找到可以构建的NPM包
    初次使用git上传代码
    JSON.parse和JSON.stringify
    vue-router Uncaught (in promise) undefined报错
    moment的安装与使用
    http://m3.codeforces.com/contest/1296/problem/E2
    题解 Codeforces Round #616 (Div. 2) (CF1291)
    codeforces 1257
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/13474214.html
Copyright © 2020-2023  润新知