【问题标题】:Build a list of list efficiently in python在 python 中有效地构建列表列表
【发布时间】:2014-04-13 08:58:18
【问题描述】:

我有以下代码:

neig = []
for _ in xrange(number):
    r = random.randint(0,self._tam-1)
    s = random.randint(0,self._tam-1)
    neig.append([r,s, self.deltaC(r, s)])

我正在尝试使用 map、生成器或其他东西来优化列表的构建来摆脱 for 循环。我检查了this answer,但就我而言,我需要为元素赋值。

是否可以使用生成器并延迟对deltaC 的调用?我认为使用map 是不可能的,因为循环体有多个语句。

【问题讨论】:

  • “延迟调用deltaC”是什么意思?您什么时候需要该值;您是否需要neig 中的所有值,并且不止一次?
  • 稍后我将在程序中使用deltaC 的值。如果我有这个列表 [1,2,deltaC(1,2)] 列表中的一个元素,¿以后可以评估吗?也许我误解了生成器的概念。如果延迟调用是不可能的,我怎样才能更有效地生成这个数组?
  • 您会多次使用该值吗?如果没有,您可以将rs 存储在列表中,然后在需要该值的地方调用deltaC(r, s)。哪个更重要 - 运行时间还是内存使用?
  • “更有效地生成这个数组” - 你能澄清一下你所说的更有效是什么意思,即当前方法有什么问题?是因为deltaC返回了一个非常庞大的结构,还是number非常大,以至于无法将整个列表保留到内存中?如果是这种情况,生成器可能会有所帮助。

标签: python list matrix


【解决方案1】:

尝试使用列表推导;

In [1]: import random

In [2]: number = 20

In [3]: tam = 13

In [4]: r = [random.randint(0, tam) for _ in range(number)]

In [5]: s = [random.randint(0, tam) for _ in range(number)]

In [6]: zip(r, s)
Out[6]: [(3, 12), (6, 12), (7, 12), (5, 1), (1, 0), (4, 12), (4, 5), (6, 2), (10, 6), (6, 11), (12, 6), (10, 2), (5, 2), (3, 2), (3, 11), (13, 2), (0, 2), (7, 0), (9, 13), (0, 12)]

In [7]: def deltaC(a, b):
   ...:     return a + b
   ...: 

In [8]: neig = [[p, q, deltaC(p, q)] for p, q in zip(r, s)]

In [9]: neig
Out[9]: [[3, 12, 15], [6, 12, 18], [7, 12, 19], [5, 1, 6], [1, 0, 1], [4, 12, 16], [4, 5, 9], [6, 2, 8], [10, 6, 16], [6, 11, 17], [12, 6, 18], [10, 2, 12], [5, 2, 7], [3, 2, 5], [3, 11, 14], [13, 2, 15], [0, 2, 2], [7, 0, 7], [9, 13, 22], [0, 12, 12]]

【讨论】:

    【解决方案2】:

    你可以使用generator expression:

    neig = ((r, s, self.deltaC(r, s))
            for r, s in ([random.randint(0,self._tam-1),
                          random.randint(0,self._tam-1)]
                         for _ in xrange(number)))
    

    前提是您只需要迭代neig 一次。

    这将延迟对 self.deltaC(r, s) 的调用,直到需要它们,因为 neig 已迭代。

    【讨论】:

    • 谢谢,但我不记得我需要按deltaC 的值对列表中的所有项目进行排序,所以这里的生成器似乎不起作用。
    【解决方案3】:

    我推荐的最好方法是使用 numpy:

    import numpy as np
    r, s = np.random.randint(0, self._tam, (2, number))
    neig = np.concatenate([r, s, self.deltaC(r, s)])
    

    这假设deltaC 可以写成接受rs 的向量,这应该很容易。请注意,np.random.randint 在上限上是独占的(与 random.randint 不同)。

    【讨论】:

    • 我稍后会尝试,现在我必须走了,deltaC 接受两个整数表示列表中的索引。如果您有使用numpy 的经验,如果您能帮我优化deltaC (stackoverflow.com/q/23033416/1612432),我将不胜感激,因为我在那里遇到了巨大的瓶颈。
    猜你喜欢
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    • 2018-02-21
    • 2018-09-02
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多