Попытка понять функцию снижения в Python - PullRequest
1 голос
/ 11 июня 2019

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

Я хотел знать, что представляют собой k и v, используемые в лямбде? Я думал, что это представляло, как это ......

k = dictionary ?
v = string ? # Did I understand it correctly?

dictionary = {"test":"1", "card":"2"}
string = "There istest at the cardboards"

from functools import reduce
res = reduce(lambda k, v: k.replace(v, dictionary[v]), dictionary, string)

, так как мы используем лямбду, тогда он зацикливает каждый элемент в обеих этих переменных. Но почему к.ремени? Разве это не словарь? Это должно быть v.replace? Как-то этот метод работает. Я хотел бы, чтобы кто-то мог объяснить мне, как это работает, и, пожалуйста, более подробно, если это возможно. Спасибо!

1 Ответ

1 голос
/ 11 июня 2019

reduce эквивалентно повторному вызову функции.

Функция в этом случае является лямбда-выражением, но лямбда-выражением является просто анонимная функция:

def f(k, v):
    return k.replace(v, dictionary[v])

Определениеreduce само по себе (почти - None значение по умолчанию здесь не совсем правильное, ни len тест):

def reduce(func, seq, initial=None):
    if initial is not None:
       ret = initial
       for i in seq:
           ret = func(ret, i)
       return ret
    # initial not supplied, so sequence must be non-empty
    if len(seq) == 0:
        raise TypeError("reduce() of empty sequence with no initial value")
    first = True
    for i in seq:
        if first:
            ret = i
            first = False
        else:
            ret = func(ret, i)
    return ret

Итак, спросите себя, что бы сделал этот при вызове вашей лямбда-функции.Цикл:

for i in dictionary

будет повторяться по каждому ключу в словаре.Он передаст этот ключ вместе с сохраненным ret (или аргументом initial для первого вызова) вашей функции.Таким образом, вы получите каждый ключ плюс строковое значение, которое изначально "There istest at the cardboards", как ваши v (ключ из словаря, называемый i в расширении reduce) и k (длинная строка, называемая ret в расширении reduce) аргументов.

Обратите внимание, что k является полнотекстовой строкой, а не строкой, используемой в качестве ключа в словаре, в то время как v является словомэто ключ в словаре. Я использовал здесь имена переменных k и v только потому, что вы это сделали.Как отмечено в комментарии, text и word могут быть лучше именами переменных в расширенной def f(...) или исходной функции lambda.

Отслеживать выполнение кода

Попробуйтетот же код, за исключением того, что вместо просто:

def f(k, v):
    return k.replace(v, dictionary[v])

вы пишете его как:

def f(text, word):
    print("f(text={!r}, word={!r})".format(text, word))
    replacement = dictionary[word]
    print("  I will now replace {!r} with {!r}".format(word, replacement))
    result = text.replace(word, replacement)
    print("  I got: {!r}".format(result))
    return result

Запустите функцию functools.reduce над функцией f с помощью dictionary и string в качестве двух других аргументов и обратите внимание на вывод.

...