2012-04-22 2 views
0

Я пытаюсь написать функцию pairSum (данные, значение), в которой, если в списке «данные» содержится два дисторных номера, сумма которых равна «значению», функция возвращает true. Я выполнил это с помощью списка, но есть ли более эффективный способ написать эту функцию, используя словари?Python pairSum function со словарями

+2

Возможно, вам следует уточнить, есть ли в списке * пары * чисел или просто * одиночные * числа. –

+0

Моя первоначальная функция имела индивидуальные номера, и я пытаюсь реализовать ту же основную функцию, используя словарь. –

ответ

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 
+0

Ницца! Ваше решение O (n), нам действительно не нужно вычислять все возможные комбинации здесь. – Akavall

1
from itertools import combinations 

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

EDIT Педро Werneck отметил, что испытание членство на set() может быть более эффективным:

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

ДАЛЕЕ EDIT Я принял совет Игнасио, и протестировали два метода с использованием timeit. Результаты приведены ниже:

для всех испытаний проверенные функции идентичны тем, которые я опубликовал в своем первоначальном ответе (см. Выше).

timeit число казней составляет 10.000

data = range(100)

Test Value Generator  Set
   1  0.02824  10.84905
  101  0.66934  10.77293
  197 11.07062  10.73978

Так что вывод, кажется, что генератор работает быстрее, в среднем, с обоих худшие времена дела для множества и генератора о том же.

+1

any() выполняет линейный поиск, поэтому значение в наборе (сумма (i) для i в комбинациях (данные, 2)), вероятно, более эффективно. –

+0

@Pedro: Генерация набора по-прежнему будет линейной, поэтому вы ничего не сможете сэкономить. –

+0

@PedroWerneck: Хммм, я не уверен. Я думаю, что это будет зависеть от размера «комбинаций». 'any (sum (i) ...' является выражением генератора и не требует вычисления всех значений до оценки. –

0

Не словарь, но вы можете построить все комбинации и проверить, находится ли ваше значение в этом наборе.

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))) 
Смежные вопросы