Передать аргументы массива в функцию

Пытаюсь передать по одному аргументу массива в функцию, но в выводе пишет None, хотя если просто число вводить, то работает нормально.

main.py:

summ = [88, 87, 126, 78, 122]

for k in range(len(summ)):
    print(p.summarise(hash_table, summ[k]))

p.py:

def summarise(hash_table, sum):
    pairs = []
    for i in range(len(hash_table)):
        for j in range(len(hash_table[i])):
            if sum == (hash_table[i][0] + hash_table[j][0]):
                if (hash_table[i][0], hash_table[j][0]) not in pairs and (hash_table[j][0], hash_table[i][0]) not in pairs:
                    pairs.append((hash_table[i][0], hash_table[j][0]))
                    return(pairs)

Ответы (1 шт):

Автор решения: hedgehogues

Ваша проблема в том, что Вы возвращаете из функции значение далеко не всегда. В частности, если все циклы полностью выполнятся, то будет возвращено None. Это легко увидеть, если переписать код в эквивалентном виде:

def summarise(hash_table, sum):
    pairs = []
    for i in range(len(hash_table)):
        for j in range(len(hash_table[i])):
            if sum == (hash_table[i][0] + hash_table[j][0]):
                if (hash_table[i][0], hash_table[j][0]) not in pairs and (hash_table[j][0], hash_table[i][0]) not in pairs:
                    pairs.append((hash_table[i][0], hash_table[j][0]))
                    return(pairs)
    return None

Теперь, для того, чтобы не получать None, можно поступить так:

def summarise(hash_table, sum):
    pairs = []
    for i in range(len(hash_table)):
        for j in range(len(hash_table[i])):
            if sum == (hash_table[i][0] + hash_table[j][0]):
                if (hash_table[i][0], hash_table[j][0]) not in pairs and (hash_table[j][0], hash_table[i][0]) not in pairs:
                    pairs.append((hash_table[i][0], hash_table[j][0]))
                    return(pairs)
    return pairs

Следует отметить, что не следует возвращать в одной и той же функции None и НЕ None в разных случаях. Это нарушает сигнатуру функции и усложняет логику. Если Вам нужно возвращать специфичное значение, Вы можете воспользоваться либо дополнительным возвращаемым аргументом:

def summarise(hash_table, sum):
    pairs = []
    for i in range(len(hash_table)):
        for j in range(len(hash_table[i])):
            if sum == (hash_table[i][0] + hash_table[j][0]):
                if (hash_table[i][0], hash_table[j][0]) not in pairs and (hash_table[j][0], hash_table[i][0]) not in pairs:
                    pairs.append((hash_table[i][0], hash_table[j][0]))
                    return pairs, True
    return [], False # Здесь можно возвращать `None`, но лучше пустой массив.

Вы также можете сгенерировать исключение:

def summarise(hash_table, sum):
    pairs = []
    for i in range(len(hash_table)):
        for j in range(len(hash_table[i])):
            if sum == (hash_table[i][0] + hash_table[j][0]):
                if (hash_table[i][0], hash_table[j][0]) not in pairs and (hash_table[j][0], hash_table[i][0]) not in pairs:
                    pairs.append((hash_table[i][0], hash_table[j][0]))
                    return pairs
    raise Exception('my exception')

Снаружи Вы его можете перехватить.

Следует также отметить, что не стоит писать так много вложенных конструкций. Читать их сложно. Лучше так:

def summarise(hash_table, sum):
    pairs = []
    for i in range(len(hash_table)):
        # Также, лучше переработать эту функцию так, чтобы вынести один из циклов в отдельную функцию.
        for j in range(len(hash_table[i])):
            if sum != (hash_table[i][0] + hash_table[j][0]):
                continue
            a = (hash_table[i][0], hash_table[j][0]) not in pairs
            b = (hash_table[j][0], hash_table[i][0]) not in pairs
            if a and b:
                pair = (hash_table[i][0], hash_table[j][0])
                pairs.append(pair)
                return pairs, True
    return [], False
→ Ссылка