【问题标题】:Populate list or tuple from callable or lambda in python从 python 中的可调用或 lambda 填充列表或元组
【发布时间】:2012-02-01 00:06:43
【问题描述】:

这是我最近经常遇到的问题。谷歌似乎没有答案,所以我把它带给堆栈溢出的好人。

我正在寻找一种简单的方法来使用函数的输出填充列表。像这样的:

fill(random.random(), 3) #=> [0.04095623, 0.39761869, 0.46227642]

这是我发现的其他方法。但我对它们并不满意,因为它们似乎效率低下。

results = []
for x in xrange(3): results.append(random.random())
#results => [0.04095623, 0.39761869, 0.46227642]

map(lambda x: random.random(), [None] * 3)
#=> [0.04095623, 0.39761869, 0.46227642]

建议?


感谢您的所有回答。我知道还有一种更像 python 的方式。

还有效率问题...

$ python --version
Python 2.7.1+
$ python -m timeit "import random" "map(lambda x: random.random(), [None] * 3)"
1000000 loops, best of 3: 1.65 usec per loop
$ python -m timeit "import random" "results = []" "for x in xrange(3): results.append(random.random())"
1000000 loops, best of 3: 1.41 usec per loop
$ python -m timeit "import random" "[random.random() for x in xrange(3)]"
1000000 loops, best of 3: 1.09 usec per loop

【问题讨论】:

  • mapfilter 如果知道列表推导是没用的...
  • “因为它们似乎效率低下”?你用timeit测量了什么?
  • 响应 timeit 测量:您测量的是初始开销。 对于 n=3,所有算法都很快。尝试 300 或 3000 以更好地了解性能。另请注意,一个好的 Python 实现(例如 PyPy)可能会内联所有变体并执行相同的代码。

标签: python arrays list tuples callable


【解决方案1】:
   list =  [random.random() for i in xrange(3)]
   list =  [random.random() for i in [0]*3]
   list =  [i() for i in [random.random]*3]

或者:

  fill =lambda f,n: [f() for i in xrange(n)]
  fill(random.random , 3 ) #=> [0.04095623, 0.39761869, 0.46227642]

【讨论】:

    【解决方案2】:

    list comprehension 怎么样?

    [random.random() for x in xrange(3)]
    

    此外,在许多情况下,您只需要这些值一次。在这些情况下,最好使用 generator expression 即时计算值并且不需要内存分配:

    results = (random.random() for x in xrange(3))
    for r in results:
       ...
    # results is "used up" now.
    # We could have used results_list = list(results) to convert the generator
    

    顺便说一句,在 Python 3.x 中,xrange 已被 range 替换。在 Python 2.x 中,range 分配内存并预先计算所有值(如列表推导式),而 xrange 即时计算值而不分配内存(它是一个生成器)。

    【讨论】:

      【解决方案3】:

      为什么你认为它们效率低?

      还有另一种方法,列表理解

      listt= [random.random() for i in range(3)]
      

      【讨论】:

        【解决方案4】:

        更通用的东西...

        from random import random
        
        fill = lambda func, num: [func() for x in xrange(num)]
        # for generating tuples:
        fill = lambda func, num: (func() for x in xrange(num))
        
        
        # then just call:
        fill(random, 4)
        # or...
        fill(lambda : 1+2*random(), 4)
        

        【讨论】:

          【解决方案5】:

          列表理解可能是最清楚的,但对于itertools afficionado:

          >>> list(itertools.islice(iter(random.random, None), 3))
          [0.42565379345946064, 0.41754360645917354, 0.797286438646947]
          

          timeit 的快速检查表明,对于超过 10 个项目,itertools 版本的速度稍快一些,但仍然可以使用您认为最清楚的任何内容:

          C:\Python32>python lib\timeit.py -s "import random, itertools" "list(itertools.islice(iter(random.random, None), 10))"
          100000 loops, best of 3: 2.93 usec per loop
          
          C:\Python32>python lib\timeit.py -s "import random, itertools" "[random.random() for _ in range(10)]"
          100000 loops, best of 3: 3.19 usec per loop
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-08-09
            • 2023-01-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-05-26
            相关资源
            最近更新 更多