gpt4 book ai didi

python - 查找可能的唯一固定长度排列数的最有效方法?

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:17:03 25 4
gpt4 key购买 nike

我有这本字典:

num_dict = {
(2, 3): [(2, 2), (4, 4), (4, 5)],
(2, 2): [(2, 3), (4, 4), (4, 5)],
(4, 5): [(4, 4)],
(1, 0): [(1, 1), (2, 2), (2, 3), (4, 4), (4, 5)],
(4, 4): [(4, 5)],
(1, 1): [(1, 0), (2, 2), (2, 3), (4, 4), (4, 5)],
}

我需要找到每个元组的第一个值的 3 个长组合的最大数量,其中只有每个键的值才能继续所述键。

我目前用于查找所有唯一(3 长)组合的代码是这样的:

ans_set = set()
for x in num_dict:
for y in num_dict[x]:
for z in num_dict[y]:
ans_set.add((x[0], y[0], z[0]))
return len(ans_set)

这将返回 10 并且ans_set 最终为:

{
(2, 2, 2), (1, 2, 2), (1, 4, 4),
(2, 2, 4), (1, 1, 2), (4, 4, 4),
(1, 2, 4), (1, 1, 4), (1, 1, 1),
(2, 4, 4)
}

但我实际上并不关心集合是什么,只关心集合的数量

这种方法并不是特别有效,因为它实际上会生成所有可能的组合并将其放入一个集合中。

我不需要知道每个独特的组合,我只需要知道有多少。

我觉得这可以做到,或许可以使用值列表的长度?但我无法理解它。

欢迎澄清有关我需要什么的问题,因为我意识到我可能没有以最清晰的方式解释它。

最终编辑

通过重新评估我需要它做的事情,我找到了查找三元组数量的最佳方法。该方法实际上并没有找到三元组,它只是对它们进行计数。

def foo(l):
llen = len(l)
total = 0
cache = {}
for i in range(llen):
cache[i] = 0
for x in range(llen):
for y in range(x + 1, llen):
if l[y] % l[x] == 0:
cache[y] += 1
total += cache[x]
return total

这里有一个解释思考过程的函数版本(不适合大列表,因为垃圾打印):

def bar(l):
list_length = len(l)
total_triples = 0
cache = {}
for i in range(list_length):
cache[i] = 0
for x in range(list_length):
print("\n\nfor index[{}]: {}".format(x, l[x]))
for y in range(x + 1, list_length):
print("\n\ttry index[{}]: {}".format(y, l[y]))
if l[y] % l[x] == 0:
print("\n\t\t{} can be evenly diveded by {}".format(l[y], l[x]))
cache[y] += 1
total_triples += cache[x]
print("\t\tcache[{0}] is now {1}".format(y, cache[y]))
print("\t\tcount is now {}".format(total_triples))
print("\t\t(+{} from cache[{}])".format(cache[x], x))
else:
print("\n\t\tfalse")
print("\ntotal number of triples:", total_triples)

最佳答案

如果我没猜错:

from itertools import combinations

num_dict = {
(2, 3): [(2, 2), (4, 4), (4, 5)],
(2, 2): [(2, 3), (4, 4), (4, 5)],
(4, 5): [(4, 4)],
(1, 0): [(1, 1), (2, 2), (2, 3), (4, 4), (4, 5)],
(4, 4): [(4, 5)],
(1, 1): [(1, 0), (2, 2), (2, 3), (4, 4), (4, 5)]
}
set(combinations([k[0] for k in num_dict.keys()], 3))

输出:

{(1, 4, 1),
(2, 1, 1),
(2, 1, 4),
(2, 2, 1),
(2, 2, 4),
(2, 4, 1),
(2, 4, 4),
(4, 1, 1),
(4, 1, 4),
(4, 4, 1)}

len()10

所以基本上你会做什么,用 itertools.combinations 进行所有组合,从长度为 3 的 dict 键的第一个元素开始,然后获取 set 以消除重复元素。

更新

由于您使用所需的输出数据更新了问题

您可以执行以下操作

from itertools import combinations_with_replacement
list(combinations_with_replacement(set([k[0] for k in num_dict.keys()]), 3))

输出:

[(1, 1, 1),
(1, 1, 2),
(1, 1, 4),
(1, 2, 2),
(1, 2, 4),
(1, 4, 4),
(2, 2, 2),
(2, 2, 4),
(2, 4, 4),
(4, 4, 4)]

UPD2

关于耗时我已经跑完了

num_dict = {
(2, 3): [(2, 2), (4, 4), (4, 5)],
(2, 2): [(2, 3), (4, 4), (4, 5)],
(4, 5): [(4, 4)],
(1, 0): [(1, 1), (2, 2), (2, 3), (4, 4), (4, 5)],
(4, 4): [(4, 5)],
(1, 1): [(1, 0), (2, 2), (2, 3), (4, 4), (4, 5)]
}
def a(num_dict):
ans_set = set()
for x in num_dict:
for y in num_dict[x]:
for z in num_dict[y]:
ans_set.add((x[0], y[0], z[0]))
return len(ans_set)
def b(num_dict):
from itertools import combinations_with_replacement
return len(list(combinations_with_replacement(set([k[0] for k in num_dict.keys()]), 3)))
%timeit a(num_dict)
%timeit b(num_dict)

结果是:

The slowest run took 4.90 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 12.1 µs per loop

The slowest run took 5.37 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 4.77 µs per loop

所以我在这里提出的解决方案快了 2 倍。

关于python - 查找可能的唯一固定长度排列数的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39947858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com