将以下字典展开为以下列表

ish*_*007 -2 python algorithm python-3.x superpermutation

如何从以下字典生成以下列表

d = {2: 4, 3: 1, 5: 3}

f = [
    2**1,2**2, 2**3, 2**4, 3**1, 5**1, 5**2, 5**3, 
    2**1 * 3, 2**2 * 3, 2**3 * 3, 2**4 * 3, 5**1 * 3, 5**2 * 3, 5**3 * 3, 
    2**1 * 5, 2**2 * 5, 2**3 * 5, 2**4 * 5, 
    2**1 * 5**2, 2**2 * 5**2, 2**3 * 5**2, 2**4 * 5**2, 3**1 * 5**2, 
    2**1 * 5**3, 2**2 * 5**3, 2**3 * 5**3, 2**4 * 5**3, 3**1 * 5**3, 
    2**1 * 3**1 * 5**1, 2**1 * 3**1 * 5**2, 2**1 * 3**1 * 5**3, 
    2**2 * 3**1 * 5**1, 2**2 * 3**1 * 5**2, 2**2 * 3**1 * 5**3, 
    2**3 * 3**1 * 5**1, 2**3 * 3**1 * 5**2, 2**3 * 3**1 * 5**3, 
    2**4 * 3**1 * 5**1, 2**4 * 3**1 * 5**2, 2**4 * 3**1 * 5**3, 
    ]
Run Code Online (Sandbox Code Playgroud)

此外,我想扩展更一般的情况,即 k 个键值对的字典

编辑:模式的解释:每个键都被提升到它的值的 0 次幂,之后对于每个术语,我们都会与其他键中的类似术语进行组合。

我可以考虑以递归方式这样做。欢迎任何非回避的方法。

PS:顺序并不重要

Kel*_*ndy 6

一种方法是,用每个可能的因素及其功效来扩展列表:

f = [1]
for k, v in d.items():
    f += [x * k**i
          for x in f 
          for i in range(1, v+1)]
Run Code Online (Sandbox Code Playgroud)

也许更快,反复乘以因子而不是计算能力:

f = [1]
for k, v in d.items():
    g = f
    for _ in range(v):
        g = [x * k for x in g]
        f += g
Run Code Online (Sandbox Code Playgroud)

有点棘手的版本很短,我相信很快(由OP在评论中确认):

from itertools import islice, repeat
from operator import mul

f = [1]
for k, v in d.items():
    f += map(mul, repeat(k, len(f) * v), f)
Run Code Online (Sandbox Code Playgroud)

一种完全不同的方法,首先计算每个因素的功效,然后使用itertools.productmath.prod将它们组合起来:

from itertools import product, accumulate, repeat
from math import prod

f = list(map(prod, product(*[[k**i for i in range(v+1)]
                             for k, v in d.items()])))
Run Code Online (Sandbox Code Playgroud)

所有的数字都包含1在列表中。如果这是一个问题,只需将其删除即可。

  • @BobMcCheese Meh,3.8 现在已经超过 2.5 岁了,所以我不想再指出这一点了:-) (2认同)
  • 第三名是速度上的胜利者。这是一些较大 v 的时间,`7.25 2.80 2.08 6.45` (2认同)