繁体   English   中英

为什么这个 Python dict 理解需要永远运行?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM