【发布时间】:2014-06-23 19:39:05
【问题描述】:
我有以下递归生成器,它产生从0 到top-1 的每个数字组合:
def f(width, top):
if width == 0:
yield []
else:
for v in range(top):
for subResult in f(width - 1, top):
yield [ v ] + subResult
如果调用为f(3, 3),则会产生值
[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2],
[0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0], [1, 0, 1], [1, 0, 2],
[1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 2, 0], [1, 2, 1], [1, 2, 2],
[2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2],
[2, 2, 0], [2, 2, 1], [2, 2, 2]
(尝试将其称为list(f(3,3)) 以获取这些列表。)
我需要以不同的顺序获得相同的值:我希望这些值按最大值排序,即。 e.首先是值[0, 0, 0],然后是所有以1 为最大值的值,即。 e. [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], ...,然后是那些包含2,即。 e. [0, 0, 2], [0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [2, 0, 0], ...等
生成器永远不会产生两次值(当然),并且必须可以使用非常大的值(例如 f(4, 1000))调用它,然后根本不会完全耗尽它(因此首先生成所有值,然后在它们的最大值之后对其进行排序是不可能的)。
我能想到的唯一方法是首先为f(w, 0) 生成所有值,然后为f(w, 1) 生成所有值,然后为f(w, 2) 生成所有值,并且总是跳过之前生成的值,但我有一种唠叨的感觉,他们可能是更好的方法:
def g(width, top):
for t in range(top):
for v in f(width, t+1):
if t in v:
yield v
有什么想法吗?
【问题讨论】:
-
您对两个具有相同最大值的列表有首选顺序吗?
-
嗯,不是真的,但我认为
g产生的订单是最不令人惊讶的订单之一 ;-) -
老实说,您对
g的实现与我的做法差不多。有一些方法可以避免跳过,但增加的复杂性可能不值得。 -
“下一个排列”版本现已编码(请参阅答案)。
标签: python algorithm generator combinations