Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这两种解决方案(lambda或loop-Python)之间的区别是什么_Python - Fatal编程技术网

这两种解决方案(lambda或loop-Python)之间的区别是什么

这两种解决方案(lambda或loop-Python)之间的区别是什么,python,Python,我想计算一个域中偶数的和。我有两种解决方案,但我不确定每种方案的优缺点。哪一个是最佳解决方案 import sys domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Cal1 = sum(filter(lambda n : n % 2 == 0, domain)) Cal2 = sum([n for n in domain if n % 2 == 0]) sys.stdout.write("Cal1 = {0}\n".format(Cal1)) sys.stdou

我想计算一个域中偶数的和。我有两种解决方案,但我不确定每种方案的优缺点。哪一个是最佳解决方案

import sys
domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Cal1 = sum(filter(lambda n : n % 2 == 0, domain))
Cal2 = sum([n for n in domain if n % 2 == 0])
sys.stdout.write("Cal1 = {0}\n".format(Cal1))
sys.stdout.write("Cal2 = {0}\n".format(Cal2))

第二个应该只是一个生成器,而不是一个列表理解(因为您实际上不需要创建一个列表来对生成器的输出求和):

它现在是完成这项任务的首选(“pythonic”)方式

  • 使用列表理解(包括
    []
    ,原始的
    Cal2
    )是不利的,因为它实际上构造了一个要返回的列表对象,这会产生开销

  • 使用
    filter
    (您的
    Cal1
    )相当于一个生成器(no-
    []
    版本),但需要更多的键入,而且读起来不如使用生成器表达式(我上面发布的代码)


    • 你的第二种方法是所谓的列表理解。列表理解可以用来实现您在引入该语言之前将要使用的
      过滤器
      映射
      。有关列表理解与地图的讨论,请参阅,该讨论与您的问题类似


      正如我所写的,推荐的Python方法是使用生成器。通过列表压缩,将生成整个过滤列表,然后进行汇总。在生成器中,它在运行时进行求和,而在内存中没有完整的列表。当你处理10项以上的问题时,这会产生更大的影响。

      +1其他重要答案

      奖励:生成器表达式更快

      $ python -m timeit -s 'L = xrange(10)' 'sum(filter(lambda n: n % 2 == 0, L))'
      100000 loops, best of 3: 3.59 usec per loop
      
      $ python -m timeit -s 'L = xrange(10)' 'sum(n for n in L if n % 2 == 0)'
      100000 loops, best of 3: 2.82 usec per loop
      

      .

      以下是旧版Mac笔记本电脑上各种版本的速度:

      $ py26 -mtimeit -s'domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]' 'sum(filter(lambda n : n % 2 == 0, domain))'
      100000 loops, best of 3: 4.41 usec per loop
      $ py26 -mtimeit -s'domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]' 'sum([n for n in domain if n % 2 == 0])'
      100000 loops, best of 3: 2.69 usec per loop
      $ py26 -mtimeit -s'domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]' 'sum(n for n in domain if n % 2 == 0)'
      100000 loops, best of 3: 2.86 usec per loop
      

      请注意,尽管genexp版本无疑更酷,但listcomp的速度稍快一些(可能还不足以让人担心,除非这段代码处于一个紧密的内部循环中,您正努力从;-)中优化snot)。与往常一样,基于
      lambda
      的版本要慢得多,正如其他人所提到的--
      lambda
      在Python中是一种“糟糕的关系”:((((
      def
      ined函数在这里也不会表现得明显更好))

      thanx亲爱的^ ^ ^那么,Lambda有什么用呢?我怎么能在我的程序中使用呢?示例plz.<代码>Lambda用于当你需要将一个短函数传递给某个东西时,而该函数只是输入的一个基本转换。例如,Python库中的一些
      排序
      函数允许你传递一个fu如果你想用一种非标准的方式对列表进行排序,那么你可以使用类似于
      lambda x,y:
      。另外,不客气。@Karamela:Example:
      reduce(lambda acc,(i,x):acc^i^x,enumerate(arr),0)
      aha。。thanx,现在我明白了:现在用1000000个数字的域名试试,看看会发生什么。生成器具有设置开销,但使用的内存和复制更少。在100k和1M元素之间的某个地方,生成器版本会变得更快。@Andrew,这取决于可用(和可寻址;-)RAM的数量——只要所有东西都适合可寻址和物理可用的RAM listcomp,则速度更快。正如你所说,有一百万个数字(Q的域乘以100000),和往常一样是旧的macbook:genexp 178毫秒,listcomp 154毫秒——你为什么不测量一下,而不是夸夸其谈呢?当然,在某种程度上,物理可用/可寻址RAM将耗尽,listcomp将严重减速,甚至在genexp仍能工作的情况下出现故障——但在任何速度超过一百万秒的体面现代机器上,@Andrew,你说listcomp做额外的复制也是完全错误的——它只是把计算出的项目放在不同的位置,而不是一次又一次地放在同一个位置——没有复制。listcomp`和genexp`都是大约
      O(N)
      (扣除了各自的一些固定开销,但这当然会摊销;-),listcomp只是有一个稍微小一些的乘数,所以它的运行速度大约快了10%(在这两个实验中分别是6%和15%)-“不必担心,除非代码在一个紧密的内部循环中”,正如我在A中所说的!嗯,listcomp确实为所有这些指针使用了更多的内存,并最终复制了它们。我在发帖前确实测量过。我的MacBook Pro上有1M个条目,listcomp 176毫秒,generator 159毫秒。原因可能是生成器将所有内容都保存在缓存中,而listcomp的中间列表不适合此CPU上的4MB处理器缓存。这是一个非常大的缓存,所以缓存较小的机器会受到更大的伤害。@Andrew McGregor:genexpr在我的机器上,对于Python 2.6.5上的1M条目的速度比listcomp稍快(
      128
      vs
      120
      ms)。用
      n&1
      替换
      n%2
      得到
      104
      vs.
      93
      ms。在Python3列表上,comp比genexpr稍快。在ideone列表上,COMP总是比genexpr快
      $ py26 -mtimeit -s'domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]' 'sum(filter(lambda n : n % 2 == 0, domain))'
      100000 loops, best of 3: 4.41 usec per loop
      $ py26 -mtimeit -s'domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]' 'sum([n for n in domain if n % 2 == 0])'
      100000 loops, best of 3: 2.69 usec per loop
      $ py26 -mtimeit -s'domain = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]' 'sum(n for n in domain if n % 2 == 0)'
      100000 loops, best of 3: 2.86 usec per loop