【问题标题】:Build hierarchized strings构建分层字符串
【发布时间】:2018-08-29 14:15:48
【问题描述】:

假设我有以下方法:

def _build_hierarchy(*keys):
     # ...

如果我调用_build_hierarchy('a', 'b', 'c', 'd'),我希望得到以下str序列:

[
    'a',
    'a:b',
    'a:c',
    'a:d',
    'a:b:c',
    'a:b:d',
    'a:b:c:d'
]

请注意,层次结构基于我提供参数的顺序。

说实话,我不知道如何处理这个问题。

理想情况下,如果有这样的事情,我想要一个非常简单和 Pythonic 的解决方案。

注意:解决方案需要兼容Python 2.7

【问题讨论】:

  • *keys的个数变量吗?更多关于构建规则的十进制会很好,它们可以被推断出来,但它仍然是猜测。
  • 为什么没有'a:c:d'

标签: python algorithm python-2.7 python-2.x


【解决方案1】:

我认为是“item的第一个length-1键应该是连续的,最后一个键可以隔离。”代码如下:

def _build_hierarchy(*keys):
    key_len = len(keys)
    result = []

    if key_len < 1:
        return result

    result.append(keys[0])
    for i in range(2, key_len + 1):
        #the first i-1 should be continuous, the last can be separate.
        pre_i = i - 1
        count = key_len - pre_i

        pre_str = ':'.join(keys[0:pre_i])
        for j in range(0, count):
            result.append(pre_str + ':' + keys[j + pre_i])

    return result


print _build_hierarchy()
print _build_hierarchy('a', 'b', 'c', 'd')

【讨论】:

    【解决方案2】:

    目前尚不清楚哪条一般规则 a:c:d 没有出现在您的输出中。在添加精度之前,此答案假定它只是被遗忘了。

    所需的输出接近于您输入的幂集。我们只要求第一个元素始终存在。因此,我们可以修改powerset function from itertools recipes

    from itertools import chain, combinations
    
    def _build_hierarchy (head, *tail, sep=':'):
         for el in chain.from_iterable(combinations(tail, r) for r in range(len(tail)+1)):
             yield sep.join((head,) + el)
    
    
    for s in _build_hierarchy('a', 'b', 'c', 'd'):
        print (s)
    

    输出

    a
    a:b
    a:c
    a:d
    a:b:c
    a:b:d
    a:c:d
    a:b:c:d
    

    【讨论】:

    • 另外,只是为了给您带来困难,这包括在 OP 的示例输出中 not 的“a:c:d”
    • 感谢您的更正。至于 a,c,d 我不明白它被排除在哪个一般规则之外,我必须等待 OP 添加精度
    【解决方案3】:

    你可以使用递归函数:

    def _build_hierarchy(*keys):
      def combinations(d, current = []):
        if len(current) == len(keys):
          yield current
        else:
          if current:
            yield current
          for i in d:
            if (not current and keys[0] == i) or i not in current:
              if len(current)+1 < 3 or all(c ==d for c, d in zip(keys, current[:len(current)+1])):
                for c in combinations(d, current+[i]):
                  yield c
      return sorted([i for i in combinations(keys) if i[0] == keys[0]], key=len)
    
    print [':'.join(i) for i in _build_hierarchy('a', 'b', 'c', 'd')]
    

    输出:

    ['a', 'a:b', 'a:c', 'a:d', 'a:b:c', 'a:b:d', 'a:b:c:d']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      • 2021-08-07
      • 1970-01-01
      相关资源
      最近更新 更多