Это вопрос подсказки для игры в гольф на Python.
В гольфе Python представление является функцией, определяемой как лямбда. Например,
f=lambda x:0**x or x*f(x-1)
У лямбда-формата есть два больших преимущества :
- Образец
f=lambda x:...
илиlambda x:...
корочеdef f(x):...return...
илиx=input()...print...
- Рекурсивный вызов может использоваться для цикла с небольшим объемом байтов.
Однако лямбды имеют большой недостаток - разрешать только одно выражение, без операторов. В частности, это означает отсутствие назначений, как c=chr(x+65)
. Это проблематично, когда есть длинное выражение, на значение которого нужно ссылаться дважды (или больше).
Подобные назначения E=enumerate
возможны вне функции или в качестве необязательного аргумента, но только если они не зависят от входных данных функции. Необязательные аргументы, такие как f=lambda n,k=min(n,0):...
fail, потому что ввод n
не был определен, когда k
оценивается во время определения.
В результате вы иногда повторяете длинное выражение в лямбде, потому что альтернатива - длинная не лямбда.
lambda s:s.strip()+s.strip()[::-1]
def f(s):t=s.strip();print t+t[::-1]
Точка безубыточности составляет около 11 символов ( детали ), после которой вы переключаетесь на a def
или program
. Сравните это с обычной точкой безубыточности длины 5 для повторного выражения:
range(a)+range(b)
r=range;r(a)+r(b)
print s[1:],s[1:]*2
r=s[1:];print r,r*2
Другие языки имеют обходные пути, например , Octave . Существуют известные приемы для Python, но они длинные, неуклюжие и / или ограниченного использования. Короткий, универсальный метод для имитации назначения в лямбде произвел бы революцию в гольфе Python.
Как игроку в Python можно преодолеть или обойти это ограничение? Какие потенциальные идеи им следует иметь в виду, когда они видят длинное выражение, повторяемое дважды в лямбде?
Моя цель с этим вопросом советов состоит в том, чтобы погрузиться в эту проблему и:
- Каталогизируйте и анализируйте обходные решения в гольф для фальшивых заданий внутри лямбды
- Исследуйте новые ссылки для лучших методов
Каждый ответ должен объяснить обходной путь или потенциальное преимущество.
lambda s:(s+s[::-1]).lower()
. Конечно, это не отвечает на реальный вопрос.strip
.Ответы:
eval
Само по себе это не так уж и много, но если ваше решение уже используется
eval
каким-либо образом или формой, вы обычно можете использовать эту технику.источник
Выражения присваивания в Python 3.8
Python 3.8 ( TIO ) представляет выражения присваивания , которые используют
:=
для присваивания переменной, встроенной как часть выражения.Это может быть использовано внутри
lambda
, где назначения обычно не разрешены. Для сравнения:Смотрите этот совет для более.
источник
Внутренние лямбды
Это позволяет вам определять несколько переменных одновременно.
против
намного длиннее, но если у вас есть несколько переменных или переменных, которые длиннее, которые повторяются много раз:
против
Количество символов
Начальная:
(lambda:)()
(11 байт)Первая переменная:
[space]a
(2 байта)Последующие переменные:
,b,
(3 байта)Использование:
a
(1 байт).(Также экономит на скобках)
Таким образом, это занимает
3n + 10
байты, гдеn
число переменных. Это высокая начальная стоимость, но в итоге может окупиться. Он даже возвращает свое внутреннее значение, так что вы можете вкладывать несколько (хотя это быстро станет не стоит).Это действительно полезно только для длинных промежуточных вычислений в понимании вложенного списка, так как
def f():a=...;b=...;return
обычно оно будет короче.Для 1 значения это сохраняет:,
uses * length - length - uses - 13
поэтому полезно только тогда, когда это выражение положительно.Для
n
различных выражений, используемыхu
в общей сложности, где их общая длина составляетl
:l - (3 * n) - u - 10 ( + brackets removed )
источник
Используйте список
Объявите список как параметр и используйте его
.append() or
для хранения значения:lambda s:s.lower()+s.lower()[::-1]
превращается в
lambda s,l=[]:l.append(s.lower())or l[-1]+l[-1][::-1]
Количество символов:
,l=[]
5 символовl.append()or
13 символовl[-1]
5 символов для каждого использованияТочка безубыточности
Количество добавляемого символа:
uses*(5-length) + 18 + length
В предыдущем примере инструкция
s.lower()
имеет длину 9 символов и используется 2 раза, применяя эту технику добавлено 19 символов. Если бы он использовался 7 раз, было бы сокращение на 1 символ.Количество минимальных применений к этой технике стоит
min_uses = (18+length)/(length-5)
расквитаться
list
объект таким образом[0]
,.pop()
,[x:y]
и другие функции списка могут быть использованы для трюков. высоко ситуативныйDownsides
5
Используй словарь
спасибо @Zgarb
Та же идея, что и выше. Объявить словарь в качестве параметра и использовать
.setdefault()
для хранения (и возврата) значения:lambda s:s.lower()+s.lower()[::-1]
превращается в
lambda s,d={}:d.setdefault(0,s.lower())+d[0][::-1]
Обратите внимание, что, в отличие от
list
аналога,setdefault
возвращает назначенное значение.Количество символов:
,d={}
5 символовd.setdefault(k,)
16 символовd[k]
4 символа для каждого использованияТочка безубыточности
Количество добавляемого символа:
(uses-1)*(4-length) + 21
В предыдущем примере инструкция
s.lower()
имеет длину 9 символов и используется 2 раза, применяя эту технику добавлено 16 символов. Если бы он использовался 7 раз, было бы сокращение на 1 символ.Количество минимальных применений к этой технике стоит
min_uses = 1-21/(4-length)
Расквитаться / Downsides
4
Другие соображения
lambda
вероятно, его можно отбросить и переписать функцию с помощьюdef
/input
для более короткой программы.источник
lambda s,d={}:d.setdefault(0,s.lower())+d[0][::-1]
он также многоразового использования.list.extend
чтобы добавить несколько элементов одновременно, что будет короче, чем использованиеlist.append
несколько раз.Используйте для установки переменных и возврата данных после операции следующим образом:
источник
Список понятий
Это скорее последнее средство, так как это так нечистоплотно, но вы можете сделать это
[<expression> for <variable> in <value>]
для псевдо-установки переменной в лямбде. По сути, единственный хороший момент в этом методе заключается в том, что внутреннее выражение может оставаться читаемым, что, очевидно, меньше всего беспокоит вас при игре в гольф.
источник