【问题标题】:Algorithm to generate (not quite) spanning set in Python with no set longer than 5在 Python 中生成(不完全)跨越集合的算法,集合不超过 5
【发布时间】:2012-02-12 22:00:29
【问题描述】:

接着这个问题Algorithm to generate (not quite) spanning set in Python

给定列表中的 n 个项目,例如 n = 7,因此输入:[1,2,3,4,5,6,7]

我想在 python 中生成这组集合:

[1] [2] [3] [4] [5] [6] [7]
[1] [2] [3] [4] [5] [6, 7]
[1] [2] [3] [4] [5, 6, 7]
...
...
[1, 2, 3, 4, 5] [6, 7]

但不是:

[1, 2, 3, 4, 5, 6] [7]
or
[1, 2, 3, 4, 5, 6, 7]

从上一个问题我有一个很好的答案:

def span(lst):
  yield [lst]
  for i in range(1, len(lst)):
    for x in span(lst[i:]):
      yield [lst[:i]] + x

是否可以在现有代码中工作以产生更具体的输出

谢谢

【问题讨论】:

  • “特定输出”是什么意思?你的意思是你想要确切的顺序,并且你想过滤掉它产生的第一个和最后一个列表?
  • 希望过滤掉那些包含超过 5 个单位的子集的集合。我所说的“特定输出”只是指它被过滤以排除那些具有六个或更多单元子集的集合。

标签: python algorithm


【解决方案1】:

虽然您当然可以使用 (s for s in span(lst) if max(len(g) for g in s) <= 5) 之类的推导来过滤原始函数的结果,但在这里我向您展示一个不会首先创建无效结果的递归解决方案:

def span(lst, most=float("inf")):
  if not lst:
    yield []
    return

  for i in range(1, min(len(lst), most) + 1):
    for x in span(lst[i:], most):
      yield [lst[:i]] + x

lst = [1,2,3,4,5,6,7]
n = 5
spannings = list(span(lst, n))         
print '\n'.join(map(str, spannings))

# proof that it produces the correct result
assert sorted(spannings) == sorted(s for s in span_orig(lst) if max(map(len, s)) <= n)
# proof that it produces the same result as the old
# function if called without a second argument
assert sorted(span_orig(lst)) == sorted(span(lst))

逻辑非常相似,尽管我们不能使用yield [lst]“技巧”来避免必须明确声明终止条件len(lst) == 0。总的来说,我实际上认为这更干净:)

请注意这是对原始函数的概括:如果您不给它第二个参数,它将与旧函数一样工作。

【讨论】:

    猜你喜欢
    • 2012-02-29
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多