[英]Sorted tuples from cartesian product of lists
我有列表字典,如下:
D = {'x': [15, 20],
'y': [11, 12, 14, 16, 19],
'z': [7, 9, 17, 18]}
我想一次取3个键(我将使用itertools.permutations
),然后计算我可以从每个列表中取出一个元素并将结果排序的所有方法。
对于上面显示的三个键,我会得到2:
(15, 16, 17)
(15, 16, 18)
显然,我可以做字典值的笛卡尔积,然后计算排序的那些:
answer = 0
for v_x, v_y, v_z in product(D['x'], D['y'], D['z']):
if v_x < v_y < v_z:
answer += 1
但我可以做得更好吗? 此解决方案不会针对键的数量和作为值的列表的长度进行缩放。 我尝试了一些毫无结果的调查,但我怀疑我可能必须利用键如何映射到列表值。 但是,我认为值得看看是否有一个解决方案我可以使用而无需重新执行其余的程序。
ETA:这是一个更大的例子。
D = {'a': [15, 20],
'b': [8],
'c': [11, 12, 14, 16, 19],
'd': [7, 9, 17, 18],
'e': [3, 4, 5, 6, 10, 13],
'f': [2],
'g': [1]}
有14个有效答案:
(8, 9, 10) (8, 9, 13) (8, 11, 13) (8, 12, 13) (8, 11, 17) (8, 11, 18) (8, 12, 17) (8, 12, 18) (8, 14, 17) (8, 14, 18) (8, 16, 17) (8, 16, 18) (15, 16, 17) (15, 16, 18)
您可以通过智能方式执行此操作 - 对于每个现有列表,将其中的每个数字映射到下一个大于它的数字列表中的计数。 一旦掌握了这些计数,对产品的明智总结应该可以为您提供所需的计数。
这是一个如何获得计数的例子:
D = {'x': [15, 20],
'y': [11, 12, 14, 16, 19],
'z': [7, 9, 17, 18]}
order = ['x', 'y', 'z']
pairs = zip(order[:-1], order[1:])
counts = dict()
for pair in pairs:
counts[pair[0]] = dict()
for num in D[pair[0]]:
counts[pair[0]][num] = len([el for el in D[pair[1]] if el >= num])
编辑下面的OP的编辑,以更清晰的问题,这样的问题:
你需要为这个问题构建一个动态编程解决方案(我假设你有一些DP算法的背景;如果没有,请看几个)。 假设您的原始字典有n
键。 然后你需要三个长度为n
字典,比如M1
, M2
和M3
。 对于每个键和数字, M3[key][number]
将存储number
可以作为元组的第三个元素的方式的number
(这将是相同的1)。 M2[key][number]
将是number
可以作为元组的第二个元素的方式的number
(这将必须从M3
向后动态构造),而M1[key][number]
将是方式的数量number
可以是元组的第一个元素。 M1
必须由M2
构建。 您的最终解决方案将是M1
中元素的总和。 我将把M1
, M2
和M3
的更新规则和初始化留给您。
例如,要填写M1[key][number]
中的条目,假设downkeys
是键后面的一组key
。 对于每个downkey
您将查看M2[downkey]
条目,并总结M2[downkey][num2]
的值,其中num2
大于number
。 为所有downkey
M1[key][number]
添加所有这些数字将为您提供M1[key][number]
的条目。 因此,这会为您提供有关更新M1
和M2
行的顺序的提示。
如果你认为这是一项很多工作 - 嗯,它是,但它仍然是多项式的,而不是笛卡尔积的指数。 即使是笛卡儿的产品方式 - 你必须先找到n
列表中3个的所有可能组合,然后取出产品,然后过滤它们。 那是非常昂贵的。 动态编程解决方案重用每个步骤的信息,而不是每次重新计算。
在示例中,您已经预先对所有字典列表进行了排序,因此您可以在调用itertools.product之前自行进行一些排序,以减少枚举次数:
def count_sorted(x,y,z):
from itertools import ifilter, product, imap
_x = ifilter(lambda k: k<z[-1],x)
_y = ifilter(lambda k: x[0]<k<z[-1],y)
_z = ifilter(lambda k: k > x[0],z)
return sum(imap(lambda t: t[0]<t[1]<t[2], product(_x,_y,_z)))
D = {'a': [15, 20],
'b': [8],
'c': [11, 12, 14, 16, 19],
'd': [7, 9, 17, 18],
'e': [3, 4, 5, 6, 10, 13],
'f': [2],
'g': [1]}
for key1,key2,key3 in itertools.permutations(D.keys(),3):
print '[%s, %s, %s] has %i sorted combinations'%(key1,key2,key3,count_sorted(D[key1],D[key2],D[key3]))
结果:
[a, c, b] has 0 sorted combinations
[a, c, e] has 0 sorted combinations
[a, c, d] has 2 sorted combinations
[a, c, g] has 0 sorted combinations
[a, c, f] has 0 sorted combinations
[a, b, c] has 0 sorted combinations
[a, b, e] has 0 sorted combinations
[a, b, d] has 0 sorted combinations
[a, b, g] has 0 sorted combinations
[a, b, f] has 0 sorted combinations
[a, e, c] has 0 sorted combinations
[a, e, b] has 0 sorted combinations
[a, e, d] has 0 sorted combinations
[a, e, g] has 0 sorted combinations
[a, e, f] has 0 sorted combinations
[a, d, c] has 2 sorted combinations
[a, d, b] has 0 sorted combinations
[a, d, e] has 0 sorted combinations
[a, d, g] has 0 sorted combinations
[a, d, f] has 0 sorted combinations
[a, g, c] has 0 sorted combinations
[a, g, b] has 0 sorted combinations
[a, g, e] has 0 sorted combinations
[a, g, d] has 0 sorted combinations
[a, g, f] has 0 sorted combinations
[a, f, c] has 0 sorted combinations
[a, f, b] has 0 sorted combinations
[a, f, e] has 0 sorted combinations
[a, f, d] has 0 sorted combinations
[a, f, g] has 0 sorted combinations
[c, a, b] has 0 sorted combinations
[c, a, e] has 0 sorted combinations
[c, a, d] has 6 sorted combinations
[c, a, g] has 0 sorted combinations
[c, a, f] has 0 sorted combinations
[c, b, a] has 0 sorted combinations
[c, b, e] has 0 sorted combinations
[c, b, d] has 0 sorted combinations
[c, b, g] has 0 sorted combinations
[c, b, f] has 0 sorted combinations
[c, e, a] has 4 sorted combinations
[c, e, b] has 0 sorted combinations
[c, e, d] has 4 sorted combinations
[c, e, g] has 0 sorted combinations
[c, e, f] has 0 sorted combinations
[c, d, a] has 8 sorted combinations
[c, d, b] has 0 sorted combinations
[c, d, e] has 0 sorted combinations
[c, d, g] has 0 sorted combinations
[c, d, f] has 0 sorted combinations
[c, g, a] has 0 sorted combinations
[c, g, b] has 0 sorted combinations
[c, g, e] has 0 sorted combinations
[c, g, d] has 0 sorted combinations
[c, g, f] has 0 sorted combinations
[c, f, a] has 0 sorted combinations
[c, f, b] has 0 sorted combinations
[c, f, e] has 0 sorted combinations
[c, f, d] has 0 sorted combinations
[c, f, g] has 0 sorted combinations
[b, a, c] has 2 sorted combinations
[b, a, e] has 0 sorted combinations
[b, a, d] has 2 sorted combinations
[b, a, g] has 0 sorted combinations
[b, a, f] has 0 sorted combinations
[b, c, a] has 8 sorted combinations
[b, c, e] has 2 sorted combinations
[b, c, d] has 8 sorted combinations
[b, c, g] has 0 sorted combinations
[b, c, f] has 0 sorted combinations
[b, e, a] has 4 sorted combinations
[b, e, c] has 8 sorted combinations
[b, e, d] has 4 sorted combinations
[b, e, g] has 0 sorted combinations
[b, e, f] has 0 sorted combinations
[b, d, a] has 4 sorted combinations
[b, d, c] has 7 sorted combinations
[b, d, e] has 2 sorted combinations
[b, d, g] has 0 sorted combinations
[b, d, f] has 0 sorted combinations
[b, g, a] has 0 sorted combinations
[b, g, c] has 0 sorted combinations
[b, g, e] has 0 sorted combinations
[b, g, d] has 0 sorted combinations
[b, g, f] has 0 sorted combinations
[b, f, a] has 0 sorted combinations
[b, f, c] has 0 sorted combinations
[b, f, e] has 0 sorted combinations
[b, f, d] has 0 sorted combinations
[b, f, g] has 0 sorted combinations
[e, a, c] has 12 sorted combinations
[e, a, b] has 0 sorted combinations
[e, a, d] has 12 sorted combinations
[e, a, g] has 0 sorted combinations
[e, a, f] has 0 sorted combinations
[e, c, a] has 44 sorted combinations
[e, c, b] has 0 sorted combinations
[e, c, d] has 44 sorted combinations
[e, c, g] has 0 sorted combinations
[e, c, f] has 0 sorted combinations
[e, b, a] has 8 sorted combinations
[e, b, c] has 20 sorted combinations
[e, b, d] has 12 sorted combinations
[e, b, g] has 0 sorted combinations
[e, b, f] has 0 sorted combinations
[e, d, a] has 28 sorted combinations
[e, d, c] has 52 sorted combinations
[e, d, b] has 4 sorted combinations
[e, d, g] has 0 sorted combinations
[e, d, f] has 0 sorted combinations
[e, g, a] has 0 sorted combinations
[e, g, c] has 0 sorted combinations
[e, g, b] has 0 sorted combinations
[e, g, d] has 0 sorted combinations
[e, g, f] has 0 sorted combinations
[e, f, a] has 0 sorted combinations
[e, f, c] has 0 sorted combinations
[e, f, b] has 0 sorted combinations
[e, f, d] has 0 sorted combinations
[e, f, g] has 0 sorted combinations
[d, a, c] has 4 sorted combinations
[d, a, b] has 0 sorted combinations
[d, a, e] has 0 sorted combinations
[d, a, g] has 0 sorted combinations
[d, a, f] has 0 sorted combinations
[d, c, a] has 18 sorted combinations
[d, c, b] has 0 sorted combinations
[d, c, e] has 4 sorted combinations
[d, c, g] has 0 sorted combinations
[d, c, f] has 0 sorted combinations
[d, b, a] has 2 sorted combinations
[d, b, c] has 5 sorted combinations
[d, b, e] has 2 sorted combinations
[d, b, g] has 0 sorted combinations
[d, b, f] has 0 sorted combinations
[d, e, a] has 8 sorted combinations
[d, e, c] has 16 sorted combinations
[d, e, b] has 0 sorted combinations
[d, e, g] has 0 sorted combinations
[d, e, f] has 0 sorted combinations
[d, g, a] has 0 sorted combinations
[d, g, c] has 0 sorted combinations
[d, g, b] has 0 sorted combinations
[d, g, e] has 0 sorted combinations
[d, g, f] has 0 sorted combinations
[d, f, a] has 0 sorted combinations
[d, f, c] has 0 sorted combinations
[d, f, b] has 0 sorted combinations
[d, f, e] has 0 sorted combinations
[d, f, g] has 0 sorted combinations
[g, a, c] has 2 sorted combinations
[g, a, b] has 0 sorted combinations
[g, a, e] has 0 sorted combinations
[g, a, d] has 2 sorted combinations
[g, a, f] has 0 sorted combinations
[g, c, a] has 8 sorted combinations
[g, c, b] has 0 sorted combinations
[g, c, e] has 2 sorted combinations
[g, c, d] has 8 sorted combinations
[g, c, f] has 0 sorted combinations
[g, b, a] has 2 sorted combinations
[g, b, c] has 5 sorted combinations
[g, b, e] has 2 sorted combinations
[g, b, d] has 3 sorted combinations
[g, b, f] has 0 sorted combinations
[g, e, a] has 12 sorted combinations
[g, e, c] has 28 sorted combinations
[g, e, b] has 4 sorted combinations
[g, e, d] has 20 sorted combinations
[g, e, f] has 0 sorted combinations
[g, d, a] has 6 sorted combinations
[g, d, c] has 12 sorted combinations
[g, d, b] has 1 sorted combinations
[g, d, e] has 4 sorted combinations
[g, d, f] has 0 sorted combinations
[g, f, a] has 2 sorted combinations
[g, f, c] has 5 sorted combinations
[g, f, b] has 1 sorted combinations
[g, f, e] has 6 sorted combinations
[g, f, d] has 4 sorted combinations
[f, a, c] has 2 sorted combinations
[f, a, b] has 0 sorted combinations
[f, a, e] has 0 sorted combinations
[f, a, d] has 2 sorted combinations
[f, a, g] has 0 sorted combinations
[f, c, a] has 8 sorted combinations
[f, c, b] has 0 sorted combinations
[f, c, e] has 2 sorted combinations
[f, c, d] has 8 sorted combinations
[f, c, g] has 0 sorted combinations
[f, b, a] has 2 sorted combinations
[f, b, c] has 5 sorted combinations
[f, b, e] has 2 sorted combinations
[f, b, d] has 3 sorted combinations
[f, b, g] has 0 sorted combinations
[f, e, a] has 12 sorted combinations
[f, e, c] has 28 sorted combinations
[f, e, b] has 4 sorted combinations
[f, e, d] has 20 sorted combinations
[f, e, g] has 0 sorted combinations
[f, d, a] has 6 sorted combinations
[f, d, c] has 12 sorted combinations
[f, d, b] has 1 sorted combinations
[f, d, e] has 4 sorted combinations
[f, d, g] has 0 sorted combinations
[f, g, a] has 0 sorted combinations
[f, g, c] has 0 sorted combinations
[f, g, b] has 0 sorted combinations
[f, g, e] has 0 sorted combinations
[f, g, d] has 0 sorted combinations
递归解决方案:
In [9]: f??
Definition: f(lists, triple)
Source:
def f(lists, triple):
out = set()
for i in range(len(lists)):
for x in lists[i]:
if len(triple) == 2 and triple[1] < x:
out.add(triple + (x,))
elif len(triple) == 0 or triple[0] < x:
for j in range(i+1, len(lists)):
out.update(f(lists[j:], triple + (x,)))
return out
输入:
In [10]: lists
Out[10]:
[[15, 20],
[8],
[11, 12, 14, 16, 19],
[7, 9, 17, 18],
[3, 4, 5, 6, 10, 13],
[2],
[1]]
输出:
In [11]: out = f(lists, ())
In [12]: len(out)
Out[12]: 14
In [13]: out
Out[13]:
set([(8, 9, 10),
(8, 12, 18),
(8, 11, 13),
(8, 16, 17),
(15, 16, 17),
(8, 12, 17),
(8, 14, 18),
(15, 16, 18),
(8, 11, 17),
(8, 9, 13),
(8, 14, 17),
(8, 11, 18),
(8, 12, 13),
(8, 16, 18)])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.