Идиома Python - пробелы в * arg / ** kwargs

Итак, я пытаюсь понять, как использование * в приведенном ниже примере лямбда вписывается в * arg / ** kwarg Идиомы Python.

Если я создам простую функцию summing, которая использует sum (iterable) для суммирования списка чисел, есть по крайней мере пара способов сделать это.

def summing(*x): return sum(*x)

или я видел другой код, который использует эту версию для лямбда

summing = lambda * x: sum(*x)

Что касается лямбда-версии, я действительно не понимаю, как символ * вписывается в идиому. Я предполагаю, что это не должно быть шаблоном глобуса - так что это? Используется ли он где-нибудь в Python? (Или что-то вроде "* args" нечувствительно к пробелам?)

(Этот вопрос начался с небольшого фрагмента кода, который поставил меня в тупик.)


person jay-tyler    schedule 23.04.2014    source источник
comment
да, *args нечувствителен к пробелам. * args - это то же самое.   -  person mhlester    schedule 23.04.2014
comment
В порядке. Это немного раздражает. Урезанная версия предпочтительнее?   -  person jay-tyler    schedule 23.04.2014
comment
PEP 8 еще не сделал никаких заявлений, но почти все используют *args и **kw (без пробелов между звездочками и именем аргумента).   -  person Martijn Pieters    schedule 23.04.2014
comment
@iasonas - PEP 8 заявил, что это плохая практика создавать функции, использующие lambda подобное. Вместо этого вы должны использовать def, как в вашем первом примере.   -  person    schedule 23.04.2014
comment
Спасибо. Я прочитал PEP 8 и знаю лучше, чем кодировать лямбда-версию сам, но я хотел понять, что здесь происходит. Поскольку PEP 8 ничего не говорит о пробелах arg / kwarg, я подумал, что, возможно, это что-то другое, чем * args / ** kwargs (или какое-то расширение идиомы) ...   -  person jay-tyler    schedule 23.04.2014


Ответы (1)


summing = lambda *x: sum(*x)

в основном то же самое, что и

def summing(*x): return sum(*x)

но функции предпочтительнее, так как они более читабельны и немного быстрее.

Однако вам не следует использовать ни один из приведенных выше фрагментов кода. *x позволяет использовать переменное количество аргументов, только чтобы распаковать их для sum().

Если вы хотите передать аргументы функции summing() следующим образом:

summing(1,2,3,4)

... используйте следующий код:

def summing(*x): return sum(x)

Если вы хотите вместо этого дать ему последовательность ...

summing([1,2,3,4])

... использовать это:

def summing(x): return sum(x)

Ваш вариант ...

def summing(*x): return sum(*x)

... требует, чтобы последовательность была передана (как и функция выше, следовательно, вам не нужно *x дважды!), вы не можете передать ее (1,2,3,4). sum() принимает итерацию в качестве первого аргумента, а второй - в качестве начального значения. sum(*x) выдаст вам ошибки.

person CodeManX    schedule 23.04.2014
comment
скорость не причина, не использовать лямбды. Кроме того, я думаю, что sum - это просто пример, т.е. фактическое использование внутри функции не имеет значения. В противном случае summing = sum проще и эффективнее. - person jfs; 24.04.2014
comment
... или даже проще: sum(...) без псевдонима функции. Кстати: Гвидо против лямбд. - person CodeManX; 24.04.2014
comment
использование только sum может быть неправильным по тем же причинам, по которым typedef существует в C. - person jfs; 24.04.2014
comment
@Andy Hayden исправил свой тест. Теперь версии def и lambda имеют практически одинаковую скорость. Хотя есть и другие причины не использовать лямбды (это я имел в виду в первом комментарии). - person jfs; 24.04.2014