【问题标题】:Python pairSum function with DictionariesPython pairSum 函数与字典
【发布时间】:2012-04-22 03:05:06
【问题描述】:

我正在尝试编写一个函数 pairSum(data, value),如果列表“数据”包含两个总和等于“值”的不同数字,则该函数返回 true。我使用列表完成了此操作,但有没有更有效的方法可以使用字典编写此函数?

【问题讨论】:

  • 或许您应该澄清一下列表中是否有个数字或只有单个个数字。
  • 我的原始函数有单独的数字,我正在尝试使用字典实现相同的基本函数。

标签: python class function sum dictionary


【解决方案1】:

你可以尝试使用一套。

def pairSum(data, value):
  s = set()
  for i in data:
    if (value - i) in s:
      return True
    else:
      s.add(i)
  else:
    return False

【讨论】:

  • 不错!你的解是O(n),我们这里真的不需要计算所有可能的组合。
【解决方案2】:
from itertools import combinations

pairSum = lambda data, value: any(sum(i) == value for i in combinations(data, 2))

编辑 Pedro Werneck 指出对set() 进行成员资格测试可能更有效:

pairSum = lambda data, value: value in set(sum(i) for i in combinations(data, 2))

进一步编辑 我接受了 Ignacio 的建议,并使用timeit 测试了这两种方法。结果如下:

对于所有测试,测试的功能与我在原始答案(上图)中发布的功能相同。

timeit 执行次数为 10,000

data = range(100)

测试值生成器集
 1 0.02824 10.84905
 101 0.66934 10.77293
 197 11.07062 10.73978

因此结论似乎是生成器的平均运行速度更快,集合和生成器的最坏情况时间大致相同。

【讨论】:

  • any() 进行线性搜索,因此在 set(sum(i) for i in combination(data, 2)) 中执行 value 可能更有效。
  • @Pedro:生成一个集合仍然是线性的,所以如果有什么节省的话,你可以节省一点。
  • @PedroWerneck:嗯,我不确定。我认为这取决于combinations 的大小。 any(sum(i)... 是一个生成器表达式,不需要在计算之前计算所有值。
【解决方案3】:

不是字典,但您可以构建所有组合并检查您的值是否在该集合中。

import itertools

def pairSum(data, value):
    return value in set(map(sum, itertools.combinations(data, 2)))

如果您的列表不包含零或负值,您可以只保留低于列表中目标值的值,因为将等于或高于列表中任何其他值的值相加将不匹配:

import itertools

def pairSum(data, value):
    data = [v for v in data if v < value]
    return value in set(map(sum, itertools.combinations(data, 2)))

【讨论】:

    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多