Сумма двух, передайте значение изнутри вызову функции?

#python #python-3.7

Вопрос:

Я попытался передать уникальные пары, сумма которых соответствует цели, в вызов функции. Что-то новенькое в python, так что дайте мне знать, как я могу это исправить.

 array = [ 3, 4, 5, 9, 10, -1, 6 ]
target = 9
def twoSum (array, target):
    for i in range(0, len(array)):
        for x in range( i   1, len(array)):
            totalOfTwo = array[i]   array[x]
            if (totalOfTwo == target):
                pairsList = (array[i], array[x])
    return -1
result = twoSum (array, target)

if result != -1:
    print ("the intergers numbers meet target", result)
else:
    print ("result is not in range")
 

Комментарии:

1. Добро пожаловать в stack overflow! Некоторые дополнительные сведения о вашем вопросе были бы чрезвычайно полезны. В чем проблема, с которой вы столкнулись с вашим кодом? Хороший вопрос должен содержать минимальный воспроизводимый пример, результат, который вы получаете, и результат, который вы ожидаете.

2. Похоже , вы пытаетесь найти два элемента, в array которых сумма target равна, с досрочным завершением (возвращает только первую найденную такую пару). Один совет по стилю для разборчивости: поскольку вы вызываете свой первый индекс i , вызывайте второй k , нет x , что делает неясным, является ли x значением или индексом. Кроме того, Python вызывает списки списков, а не «массивы», в отличие от Java.

3. Второй совет: это более питоническое return None , чем возвращать значение sentinel, такое как -1. Затем вызывающий может проверить возвращаемое значение с помощью простого if result: , вам не нужно никакого if result != -1 или if result is None .

Ответ №1:

Вы забыли вернуть результат

Ты кодируешь

 array = [ 3, 4, 5, 9, 10, -1, 6 ]
target = 9
def twoSum (array, target):
    for i in range(0, len(array)):
        for x in range( i   1, len(array)):
            totalOfTwo = array[i]   array[x]
            if (totalOfTwo == target):
                pairsList = (array[i], array[x]) ##### THIS #####
    return -1
result = twoSum (array, target)

if result != -1:
    print ("the intergers numbers meet target", result)
else:
    print ("result is not in range")
 

Мой код

 array = [ 3, 4, 5, 9, 10, -1, 6 ]
target = 9
def twoSum (array, target):
    for i in range(0, len(array)):
        for x in range( i   1, len(array)):
            totalOfTwo = array[i]   array[x]
            if (totalOfTwo == target):
               return (array[i], array[x]) ##### THIS ####
    return -1
result = twoSum (array, target)

if result != -1:
    print ("the intergers numbers meet target", result)
else:
    print ("result is not in range")
 

Но это только первый результат, так что…

 array = [ 3, 4, 5, 9, 10, -1, 6 ]
target = 9
def twoSum (array, target):
    rsts = [] # save rsts hear
    for i in range(0, len(array)):
        for x in range( i   1, len(array)):
            totalOfTwo = array[i]   array[x]
            if (totalOfTwo == target):
               rsts.append((array[i], array[x])) # add answer to rsts
    return -rsts
result = twoSum (array, target)
 

если у нас нет правильного ответа, результатом будет пустой список ( [] ), так что

 if result != []: # changed -1 with []
    print ("the intergers numbers meet target", result)
else:
    print ("result is not in range")
 

Комментарии:

1. Хороший ответ, поскольку он помогает определить проблему, но я лично предполагал, что цель состояла в том, чтобы создать список всех комбинаций кортежей, а не возвращать первую.

2. Да, я попробовал это и вернул только первую уникальную пару. Спасибо за вашу помощь!

Ответ №2:

Я думаю, это то, что вы ищете?

Вам нужно добавить пары в список и вернуть их, если таковые будут найдены.

Кроме того, лично я бы вернул пустой список, а не -1, если он не найден, так как это разные типы данных.

 array = [ 3, 4, 5, 9, 10, -1, 6 ]
target = 9
def twoSum (array, target):
    pairsList = []
    for i in range(0, len(array)):
        for x in range( i   1, len(array)):
            totalOfTwo = array[i]   array[x]
            if (totalOfTwo == target):
                pairsList.append((array[i], array[x]))
    if len(pairsList) == 0:
        return -1
    else:
        return pairsList
result = twoSum (array, target)

if result != -1:
    print ("the intergers numbers meet target", result)
else:
    print ("result is not in range")
 

Комментарии:

1. Спасибо. Это то, что я так долго искал.

Ответ №3:

Самый простой способ реализовать это в виде списка, это всего лишь однострочник!

 >>> [(a[i],a[j]) for i in range(0, len(a)-1) for j in range(i 1, len(a)-1) if a[i] a[j]==target]

[(4, 5), (10, -1)]
 

(Обратите внимание, что это позволяет выполнить досрочное расторжение, но вы можете просто вырезать [0] — й элемент.)

Что касается вашего кода/ функционального подхода, я бы переписал его так (в следующий раз, пожалуйста, попросите отзывы о рабочем коде на CodeReview.SE, а не здесь, на SO):

 def two_sum (a, target):
    for i in range(0, len(a)):
        for j in range( i   1, len(a)):
            if a[i]   a[j] == target:
                return (a[i], a[j])
    return None

result = two_sum (a, target)

if result:
    print ("the numbers sum to target", result)
else:
    print ("result is not in range")
 

Комментарии:

  • поскольку вы называете свой первый индекс i, вызывайте второй индекс j, а не x, что делает неясным, является ли x значением или индексом
  • гораздо более по-питонски возвращать None, чем возвращать значение sentinel, например -1. Затем вызывающий может просто проверить возврат значения с помощью простого if result: , вам не нужно никакого неуклюжего if result != -1 или if result is None
  • переименован twoSum в two_sum в соответствии с соглашением об именовании Python (PEP-8) для имен функций и переменных: lower_case_with_unders
  • примечание. Эта реализация завершается досрочно. Но если вы просто измените return (a[i], a[j]) на yield (a[i], a[j]) , это сделает его генератором, который последовательно возвращает все(/любые) совпадающие кортежи. (вам нужно будет заменить return None его на yield StopIteration )
  • аналогичным totalOfTwo образом будет называться total_of_two или pair_sum
  • но нет необходимости объявлять временные переменные для totalOfTwo , pairsList , просто используйте выражения напрямую
  • рекомендую вам изучить правильную терминологию Python, если вы пришли из Java. pairsList это не список, а кортеж. array это не массив, это список. Но я бы просто назвал это a .
  • обратите внимание, что нам нужно только запустить левый индекс i до len(a)-1 вместо len(a), так как мы знаем, что нам понадобится j для индексации элемента справа от него.