Создать функцию с неограниченными параметрами

Создать функцию list_expert, которая будет принимать неограниченное количество параметров и если передали числа, то вернуть их сумму, а если есть другие типы, то вывести списком их типы. Но если ввести 1 параметр, то его же и вывести.

Ожидаемый результат:

list_expert(1,2,3,4,5)  # 15
list_expert("a", True, [1, 2, 3])  # ['str', 'bool', 'list']
list_expert("obj")  # obj

Мой код:

def list_expert(*args):
  if type(args) is int:
    if len(args) == 1:
      return args[0]
    elif len(args) > 1:
      return sum(args)
  else:
    return(list(map(type, args)))

Не пойму что не так.


Ответы (3 шт):

Автор решения: SVBazuev

Я добавил в Ваш код одну строчку:

def list_expert(*args):
    print(type(args))
    if type(args) is int:
        if len(args) == 1:
            return args[0]
        elif len(args) > 1:
            return sum(args)
    else:
        return(list(map(type, args)))

^^^ Вы можете исправить своё решение с ветвлением if


Как вариант:

def list_expert(*args):
    if (l_a := len(args)) in (0, 1):
        return args[0] if l_a else "Was called without arguments."

    if set(t_a := list(map(type, args))) <= {int, float, complex}:
        return sum(args)
    else:
        return t_a


print(list_expert())                      # Was called without arguments.
print(list_expert(10))                    # 10
print(list_expert("obj"))                 # obj
print(list_expert({'key': 'val'}))        # {'key': 'val'}
print(list_expert('1', '2'))              # [<class 'str'>, <class 'str'>]
print(list_expert(1, 2, 3, 4, 5))         # 15
print(list_expert(1.3, 2, 3.1, 4, 5.5))   # 15.9
print(list_expert("a", True))             # [<class 'str'>, <class 'bool'>]
print(list_expert(1, True))               # [<class 'int'>, <class 'bool'>]

^^^ Этот вариант работает быстрее.

Успехов!

→ Ссылка
Автор решения: mrgervant

По комментарию не совсем понятно как именно у Вас расставлены отступы, но могу предложить следующее:

  • Не нужно проверять сразу все аргументы через if type(args) is int, т.к. это будет возвращать <class 'tuple'> (кортеж в котором лежат аргументы).

  • Далее эта проверка может сломать логику if/else - в зависимости от того, как у вас они вложены.

  • Проверку типов предпочтительнее делать через isinstance() - поддерживает наследование классов (но если цель обратная, проверить без подклассов - тогда да, через type()).

  • При проверке на числа лучше сделать и проверку на то, что это не булевы значения, поскольку они могут трактоваться Python как числа 0 и 1 (True + True = 2).

  • При использовании list(map(type, args)) Вы получите список самих типов как:

    [<class 'str'>, <class 'bool'>, <class 'list'>]

    Чтобы вытащить именно имена типов, нужно сделать map немного по другому:

    list(map(lambda a: type(a).__name__, args))

  • Из функции можно выходить в любой момент - это позволяет делать меньше вложенность if/else-ов. Проверили один случай - вышли или пошли к следующей части функции, без прописывания лишних else.

  • Дополнительно рекомендуется проверять крайний случай - аргументов вообще не пришло. И возвращать None или иное другое значение.

  • Опционально: если Вам нужно работать со всеми числами, а не только с int, то можно использовать класс numbers.Number (документация)

Итого:

from numbers import Number

def is_number(value):
    return isinstance(value, Number) and not isinstance(value, bool)

def list_expert(*args):
    if len(args) == 0:
        return None
    if len(args) == 1:
        return args[0]
    if all(map(is_number, args)):
        return sum(args)
    return list(map(lambda a: type(a).__name__, args))

Вывод функции:

list_expert()                         >>>  None
list_expert(1)                        >>>  1
list_expert("obj")                    >>>  obj
list_expert(1, 2, 3, 4, 5)            >>>  15
list_expert(1.1, 2.2, 3.3, 4.4, 5.5)  >>>  16.5
list_expert(True, False)              >>>  ['bool', 'bool']
list_expert("obj", True, [1, 2, 3])   >>>  ['str', 'bool', 'list']
→ Ссылка
Автор решения: Qwertiy

tio.run

def list_expert(*args):
  if len(args) == 1:
    return args[0]

  if all(type(x) is int for x in args):
    return sum(args)

  return [type(x).__name__ for x in args]

print(list_expert(1,2,3,4,5))
print(list_expert(10))
print(list_expert("a", True, [1, 2, 3]))
15
10
['str', 'bool', 'list']
→ Ссылка