【问题标题】:Python: How to append generator iteration values to a listPython:如何将生成器迭代值附加到列表中
【发布时间】:2013-07-15 08:03:46
【问题描述】:

我有一个简单的生成器,可以给我一组坐标的排列。 我希望使用以下代码将每个新排列保存到数组中的一个元素:

import random
def poss_comb(coord):
    spin=random.shuffle
    if spin:
        spin(coord)
        yield (coord)
...

a=[]
for n in xrange(0,10):
    for item in poss_comb(coord):
        print item
        a.append(item)

但是,当打印结果时,打印 item 给了我我想要的:

['0 1', '', '1 2', '1 3']
['0 1', '', '1 2', '1 3']
['1 2', '0 1', '1 3', '']
['0 1', '1 2', '', '1 3']
['1 3', '', '1 2', '0 1']
['1 3', '1 2', '0 1', '']
['0 1', '', '1 3', '1 2']
['1 2', '0 1', '', '1 3']
['1 2', '1 3', '', '0 1']
['', '1 2', '1 3', '0 1']

而打印list a 提供了一个数组,其中每个元素都是最后一个排列的副本。

有什么更好的方法来做到这一点?

【问题讨论】:

  • 你的函数是产生全局的coord还是局部的link
  • 它们是相同的,为简单起见,我在发布时将链接更改为坐标。 (现已更正)
  • coord 到底是什么?它没有在任何地方定义。
  • 你是一个简单的生成器poss_comb() 只产生一个值。
  • 值得注意的是,有一种更简单的方法可以将生成器中的每个产生的值附加到列表中:a = list(poss_comb(coord))(或 a.extend(poss_comb(coord)),如果您想将它们附加到现有列表而不是新的)。

标签: python list iteration generator permutation


【解决方案1】:

您的生成器不会产生 new 列表,它会一遍又一遍地产生 相同的列表。当您将产生的引用附加到 a 时,您只会一遍又一遍地看到相同的原始列表,它是最近改组的形式。

改为生成副本:

def poss_comb(coord):
    coord = coord[:]  # use a local copy of the list
    random.shuffle(coord)
    yield coord

或者创建一个随机排序,而不是使用 sorted() 函数的就地改组:

def poss_comb(coord):
    yield sorted(coord, key=lambda k: random.random())

【讨论】:

  • 没有理由创建一个只调用函数的lambda;只需传递函数本身。 (编辑答案以修复它。)
  • @abarnert:这只有在random.random 接受参数时才有效。我认为你需要恢复。
  • @DSM:原始版本创建了一个不带参数的 lambda,所以这在与原始版本完全相同的情况下工作......但如果两者都不起作用,我们需要一个新的编辑......
  • 实际上……我认为这首先不是一个好主意。使用具有稳定排序(如 timsort)的不稳定键意味着无限的最坏情况时间!即使这不是问题,它仍然是 O(N log N) 而不是 O(N)。喜欢shuffle。如果这是为了避免复制列表的成本而进行的优化,那是一种悲观。如果您想要一个不需要预复制的非就地shuffled 函数,正确的方法是按随机顺序插入每个元素。但是预复制会更简单,而且可能更快。
  • @abarnert:啊,你说得对,原版也有同样的缺陷。我没有考虑过不稳定的关键方面,但我认为已指定关键功能只会为每个元素评估一次,在这种情况下,从排序的角度来看, 没有不稳定性。 (考虑算法顺序会伤脑筋,所以我会推迟考虑最坏情况的行为。)
猜你喜欢
  • 1970-01-01
  • 2014-09-06
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多