Создать функцию с неограниченными параметрами
Создать функцию 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 шт):
Я добавил в Ваш код одну строчку:
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'>]
^^^ Этот вариант работает быстрее.
Успехов!
По комментарию не совсем понятно как именно у Вас расставлены отступы, но могу предложить следующее:
Не нужно проверять сразу все аргументы через
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']
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']