【问题标题】:Setting a variable equal to a returned value from a for loop in Python将变量设置为等于 Python 中 for 循环的返回值
【发布时间】:2013-06-12 21:25:10
【问题描述】:

这将为我节省大量代码,但我不确定如何实现它。我想将我的变量“totalfactors”设置为 for 循环遍历字典并执行产品操作 (Capital Pi Notation) 的结果。所以我想我会这样写:

totalfactors = for x in dictionary: dictionary[x]*totalfactors

我知道我可以用几行这样的方式写出来:

totalfactors = 1

    for pf in apfactors:
        totalfactors *= (apfactors[pf]+1)

任何帮助都会非常有用!谢谢

【问题讨论】:

    标签: python variables for-loop


    【解决方案1】:

    您可以使用functional 内置reduce。它将重复(或递归)应用一个函数 - 这里是一个匿名 lambda - 在一个值列表上,建立一些聚合:

    >>> reduce(lambda x, y: x * (y + 1), [1, 2, 3])
    12
    

    相当于:

    >>> (1 * (2 + 1)) * (3 + 1)
    12
    

    如果你需要另一个初始值,你可以把它作为最后一个参数传递给reduce:

    >>> reduce(lambda x, y: x * (y + 1), [1, 2, 3], 10)
    240
    
    >>> (((10 * (1 + 1)) * (2 + 1)) * (3 + 1))
    240
    

    就像@DSM 在评论中指出的那样,您可能想要:

    >>> reduce(lambda x, y: x * (y + 1), [1, 2, 3], 1) # initializer is 1
    

    可以使用operator 模块和generator expression 更简洁地编写为:

    >>> from operator import mul
    >>> reduce(mul, (v + 1 for v in d.values()))
    

    我会猜到,生成器变体更快,但在 2.7 上似乎不是(至少对于非常小的字典):

    In [10]: from operator import mul
    
    In [11]: d = {'a' : 1, 'b' : 2, 'c' : 3}
    
    In [12]: %timeit reduce(lambda x, y: x * (y + 1), d.values(), 1)
    1000000 loops, best of 3: 1 us per loop
    
    In [13]: %timeit reduce(mul, (v + 1 for v in d.values()))
    1000000 loops, best of 3: 1.23 us per loop
    

    【讨论】:

    • 使用 lambda 还是 operator.mul 更好?
    • 请注意,通过阅读 OP 的第二个示例,他实际上更喜欢 2*3*4=24 作为答案。我可能会做类似reduce(mul, (v+1 for v in d.values()) 的事情。
    • 使用小字典,生成器开销淹没了速度提升。添加更多项目,生成器变体会赶上并变得更快。对我来说,交叉点是字典中的 6 个键/值对。
    • @torek,我的机器仍然运行超过 100 万个条目的基准测试。在 100000 时,两种变体都处于同等水平(4.41 秒对 4.4 秒)。
    • 有趣。也许当你达到 1M 时,算术就会接管。我在 timeit 下只做了 3、4、5 和 6 个。在任何情况下,速度都像往常一样取决于实现。 :-)
    【解决方案2】:

    听起来你可能想考虑做一个 reduce()。例如:

    >>> d={'a':1,'b':2,'c':3,'d':4}
    >>> reduce(lambda x,y: x*y, d.values())
    24
    

    【讨论】:

      【解决方案3】:

      我试图想办法用生成器来做到这一点,但我能想到的只有

      import operator
      total_product = reduce(operator.mul, dictionary.values(), 1)
      

      我测试过:

      factorial = reduce(operator.mul, xrange(1,6), 1)
      

      结果是 120。

      编辑:

      您可能已经知道这一点,但我后来想到了。如果dictionary.values() 值中有任何非数字数据,您将获得TypeError,前提是您至少有一个float。不过,当您插入字典时,您可能正在处理这个问题。

      我搞砸了一点,想出了:

      import numbers
      import operator
      
      foo = [1, 2.1, None, 4.5, 7, 'm']
      print reduce(operator.mul, [num for num in foo if isinstance(num, numbers.Number)], 1)
      

      这给了我 66.15,没有例外。它可能效率较低,但比未处理的异常更有效。

      【讨论】:

        猜你喜欢
        • 2014-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-28
        • 1970-01-01
        • 2011-07-05
        • 1970-01-01
        • 2014-01-21
        相关资源
        最近更新 更多