[英]Why is this Python dict comprehension taking forever to run?
函数pair_exists()
将两项作为输入:
nums
: 一个列表(或其他数据结构)target
:一个整数如果nums
任意两个数字总和为目标,则该函数应返回True
。 我让它运行的列表是 1 到 100 万个条目中的 10,000 个条目。 运行需要 20 多分钟(虽然我有一台 MacBook Air,所以它不是最高功率的),所以我假设它坏了和/或在计算上浪费了。 我如何让它运行?
import itertools
random.seed(a=13, version=2)
random_numbers = random.sample(range(1, 1000000), 10000)
def pair_exists(nums: list, target: int):
result = [seq for i in range(len(nums), 0, -1) for seq in itertools.combinations(nums, i) if sum(seq) == target]
print(pair_exists(random_numbers, 38109)) # SHOULD RETURN TRUE
print(pair_exists(random_numbers, 13538)) # SHOULD RETURN FALSE
不清楚为什么要检查任何大小的子集。 你的问题陈述说你只对成对感兴趣。
按照您的方法风格,我们可以在O(n^2)
编写一个解决方案:
def pair_exists(nums, target):
return any(sum(subset) == target for subset in itertools.combinations(nums, 2))
但这在大型阵列上仍然很慢。 相反,我们可以尝试使用两个迭代器,它们将在O(n)
执行O(n)
由于排序,我猜在O(n*log(n))
中)。
def pair_exists(nums, target):
nums = sorted(nums)
start = 0
end = len(nums) - 1
while start < end:
if nums[start] + nums[end] < target:
start += 1
elif nums[start] + nums[end] > target:
end -= 1
else:
return True
return False
这是 O(lots) 并且不按照名称中所说的去做; 它查找具有正确总和的任何大小的子集:
def pair_exists(nums: list, target: int):
result = [seq for i in range(len(nums), 0, -1) for seq in itertools.combinations(nums, i) if sum(seq) == target]
(此外,它不返回任何内容。)
这是 O(n²),你原来的但改编为正确的:
def pair_exists(nums: list, target: int):
return any(sum(pair) == target for pair in itertools.combinations(nums, 2))
@Bill Lynch 发布了一个 O(n log n) 的排序答案。
这是一个 O(n) 解决方案,通过确定什么会与每个值形成正确的对,并检查它是否更早出现:
from typing import Iterable
def pair_exists(nums: Iterable[int], target: int):
seen = set()
for num in nums:
if (target - num) in seen:
return True
seen.add(num)
return False
该集合是一个具有 O(1) 插入和成员资格测试的集合,允许“较早出现”检查很快。
此功能效率不高且与您使用的机器无关。
尝试类似的方法来检查您是否有对目标求和的对
def pair_exists(nums: list, target: int):
for num in nums:
if target - num in nums:
return True
return False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.