zoukankan      html  css  js  c++  java
  • 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))
    
  • 相关阅读:
    4.Linux的目录结构
    使用idea创建spring mvc项目图文教程
    传统的Servlet在spring boot中怎么实现的?
    springboot系列教程导学篇
    记录一次序列化引起的问题解决办法 查看已编译类序列化值
    springboot支付项目之springboot集成jpa
    springboot支付项目之日志配置
    设计模式之状态模式总结篇
    看了这个Java实习生入职测试题后,幸亏我不是实习生
    幂等性学习及接口的幂等性
  • 原文地址:https://www.cnblogs.com/sanduzxcvbnm/p/13474214.html
Copyright © 2011-2022 走看看