Получение функции Python для чистого возврата скаляра или списка, в зависимости от количества аргументов

Отказ от ответственности: я ищу решение Python 2.6, если оно есть.

Я ищу функцию, которая возвращает одно значение при передаче одного значения или возвращает последовательность при передаче нескольких значений:

>>> a = foo(1) 2 >>> b, c = foo(2, 5) >>> b 3 >>> c 6 

Чтобы быть ясным, это делается для того, чтобы некоторые вызовы функций выглядели лучше, чем:

 a, = foo(1) 

или

 a = foo(1)[0] 

Прямо сейчас, неэлегантное решение – это что-то вроде этого:

 def foo(*args): results = [a + 1 for a in args] return results if len(results) > 1 else results[0] 

Есть ли какой-нибудь синтаксический сахар (или функции), который сделает это чище? что-нибудь вроде следующего?

 def foo(*args): return *[a + 1 for a in args] 

5 Solutions collect form web for “Получение функции Python для чистого возврата скаляра или списка, в зависимости от количества аргументов”

Вы можете легко написать функцию scalify которая возвращает элемент из списка, если в списке есть только один элемент, т. scalify Он пытается сделать его скаляром (отсюда и название).

 def scalify(l): return l if len(l) > 1 else l[0] 

Затем вы можете использовать его в своих функциях так:

 def foo(*args): return scalify([a + 1 for a in args]) 

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

Вы всегда можете написать декоратор, чтобы убедиться, что если оператор if, если это вам лучше:

 import functools def unpacked(method): @functools.wraps(method) def _decorator(*args): result = method(*args) return results if len(results) != 1 else results[0] return _decorator 

Применение:

 @unpacked def foo(*args): return [arg + 1 for arg in args] 

Вы имеете в виду, что хотите кортеж с таким же количеством аргументов? Разве это не решение?

return tuple([a + 1 for a in args])

 def foo(*args): return (None, args[0]+1 if args else None, map(lambda a: a + 1, args))[len(args) if len(args) < 3 else 2] 

🙂 это ад

Это будет обрабатывать 0 или более аргументов, я думаю, это то, что вы ищете.

 def foo(*args): return map(lambda x: x + 1, args) or [None] 

редактирование: я переработал, чтобы добавить список «Нет», чтобы распаковать 0 аргументов

  • Как проверить, является ли объект экземпляром пользовательского класса нового стиля?
  • Эквивалент string.ascii_letters для строк unicode в python 2.x?
  • Как реализуется True <2?
  • PyGame Sprites Иногда не рисует
  • Как организовать модули Python для PyPI для поддержки 2.x и 3.x
  • Почему id () несвязанного метода в Python 2 изменяется для каждого доступа
  • Python re.sub с флагом не заменяет все вхождения
  • Вложенные аргументы не компилируются
  • Python - лучший язык программирования в мире.