Подход, предложенный @Ипатьев, в принципе неплох.
Но я считаю, стоит помнить, что питон - язык с динамической типизацией. Если какой-то тип умеет выполнять требуемые от него операции, стоит этот тип принимать. Иными словами, тебе необязательно принимать именно список или кортеж - тебе подойдёт любая коллекция, которую можно перечислить, и у которой есть длина.
Так что я бы посоветовал сделать иначе:
import collections.abc as abc
# Collection требует поддержки итерации, проверки вхождения и длины.
def avg(data_set: abc.Collection[int]) -> float: # type hint для разработчика и IDE
# если получим что-то не то, будет выкинуто TypeError - а нам это и надо.
avg = sum(data_set) / len(data_set) # такое деление вернёт float
return avg
Либо, если тебе хочется своей обработки ошибки:
import collections.abc as abc
def avg(data_set: abc.Collection[int]) -> float: # type hint для разработчика и IDE
# протокол abc.Collection можно проверять через isinstance()
if not isinstance(data_set, abc.Collection):
raise TypeError(f'data_set must be a collection of ints, got {type(data_set)}')
avg = sum(data_set) / len(data_set) # такое деление вернёт float
return avg
Иными словами, может иметь смысл определить минимально необходимый тебе набор операций, и описывать как входной тип именно его. Хотя зачастую можно и не заморачиваться. Если ты значешь, что будешь передавать в функцию только список - можешь прописывать только список.
И это будет работать:
>>> avg([1,2,3]) # список
2.0 # работает
>>> avg({1,2,3}) # множество
2.0 # работает
>>> avg(x for x in range(3)) # выражение-генератор
Traceback (most recent call last): # отказ, у генераторов нет заранее известной длины
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in avg
TypeError: data_set must be a collection of ints, got <class 'generator'>