Как связать вызовы функций Python, чтобы поведение было следующим
Я наткнулся на следующую проблему при вызове Python: написать функцию, которая удовлетворяет следующему правилу для любого числа вызовов функций.
f()()()()()(s) == 'fooooo' + s;
пример:
f('it') == 'fit';
f()('x') == 'fox';
f()()('bar') == 'foobar';
f()()()('l') == 'foool';
Функция должна быть без сохранения состояния и не должна использовать никаких переменных вне области видимости.
Подпись функции была:
def f(s=None):
# Your code here
Я подумал, что для того, чтобы иметь возможность объединять несколько вызовов, нам придется возвращать функцию, когда в функцию не передана ни одна строка, но не могу понять, как построить ожидаемую строку без внешних переменных. Предложения?
def f(s=None):
if s is None:
# concatenate an 'o'?
return f
else:
# Last call, return the result str.
return s
Ответы
Ответ 1
Альтернатива Николау ответу что-то вроде этого:
def f(s=None):
if s: return f'f{s}'
def factory(prefix):
def inner(s=None):
return f'f{prefix}{s}' if s else factory(prefix + 'o')
return inner
return factory('o')
используя замыкание и без вспомогательной функции, но я бы предпочел partial
решение.
Ответ 2
Очевидно, вам нужно хранить число "o" где-то в памяти (например, код) функции f
. Чтобы достичь этого, вы можете воспользоваться этими двумя функциями Python:
- Вы можете определить функции внутри других функций
- Там это называется связыванием аргументов, которое позволяет вам сказать Python исправить некоторые или все аргументы вашей функции. Это делается через
functools.partial
И вот решение
from functools import partial
def f(s=None):
# Define a new function g which takes the current text and takes s
def g(current_text, s=None):
if s is not None:
return current_text + s
else:
# If called with an empty argument, just rebind current_text with an extra o
return partial(g, current_text + "o")
# Just call g with the initial conditions
return g("f", s)
print(f()()()()()("s")) # fooooos
print(f("s")) # fs
Ответ 3
Вы можете попробовать это:
def f(s=None):
string = "f"
def ret(p=None):
nonlocal string
string += "o"
return ret if not p else string + p
return ret if not s else string + s
Ответ 4
Это мой путь к этому:
def f(x=None, seq=''):
if x:
return 'f' + seq + x
else:
def g(y=None, p=seq + 'o'):
return f(y, p)
return g
Редактировать Если вам действительно нужно, чтобы сигнатура функции была f(x=None)
, используйте это:
def f(x=None):
def f_(x=None, seq=''):
if x:
return 'f' + seq + x
else:
def g(y=None, p=seq + 'o'):
return f_(y, p)
return g
return f_(x)
: ^)
Ответ 5
Просто для печати строки:
def f(s=None):
def fo(s=None):
if s==None:
print('o',end='')
return fo
else:
print(s)
return
if s!=None:
print('f',end='')
print(s)
return
elif s==None:
print('fo',end='')
return fo
Ответ 6
Как это:
def f(val=None):
if val is not None:
return 'f' + str(val)
def inner1(val=None):
if val is not None:
return 'fo' + str(val)
def inner2(val=None):
if val is not None:
return 'foo' + str(val)
def inner3(val):
return 'fooo' + str(val)
return inner3
return inner2
return inner1
assert f('it') == 'fit'
assert f()('x') == 'fox'
assert f()()('bar') == 'foobar'
assert f()()()('l') == 'foool'
Ответ 7
Милая проблема. Это компактный способ сделать это:
def f(s=None, prefix="f"):
if s: return prefix + s
return lambda s=None: f(s, prefix=prefix+"o")
Ответ 8
Это действительно забавный вопрос. Я бы использовал изменяемый аргумент по умолчанию, чтобы решить это:
def f(s=None,l=[]):
if not s:
l.append("o")
return f
else:
return "f"+"".join(l)+s
Ответ 9
FP:
f=lambda s=None,prefix='f':prefix+s if s else lambda s=None,prefix=prefix+'o':f(s,prefix)