Как при превышении индексом длины списка запустить проход по списку заново?
Делаю программу на python, и возникла проблема. Есть список, например:
mylist = ['a', 'b']
, и, если индекс списка больше длины самого списка, то он должен обойти список ещё раз а не вывести ошибку. например:
mylist = ['a', 'b']
print(mylist[3])
Как сделать такое в python?
Ответы (2 шт):
Для этого нужно сделать так, чтобы index был меньше длины списка. Это делается взятием остатка.
mylist = ['a', 'b']
index = input('Индекс')
try:
index = int(index)
except:
print('Вы ввели не число!')
else:
print(mylist[index % len(mylist)])
Если целью является унификация обращений к списку без оглядки на индекс, то можно создать новый класс с опорой на list или collections.UserList:
from collections import UserList
class MyList(UserList):
def __getitem__(self, index):
return super().__getitem__(index % len(self))
seq = MyList(['a', 'b'])
print(f'{type(seq) = }')
print(f'{len(seq) = }')
print(f'{seq[3] = }')
# type(seq) = <class '__main__.MyList'>
# len(seq) = 2
# seq[3] = 'b'
Выбор в пользу collections.UserList как базового типа может быть продиктован необходимостью сохранять пользовательский тип при некоторых преобразованиях. Например:
from collections import UserList
class BuiltinListBase(list): pass
class UserListBase(UserList): pass
builtin_list_base = BuiltinListBase()
user_list_base = UserListBase()
print(f'{type(builtin_list_base) = }')
print(f'{type(builtin_list_base + []) = }')
print(f'{type(builtin_list_base + builtin_list_base) = }')
# type(builtin_list_base) = <class '__main__.BuiltinListBase'>
# type(builtin_list_base + []) = <class 'list'>
# type(builtin_list_base + builtin_list_base) = <class 'list'>
print(f'{type(user_list_base) = }')
print(f'{type(user_list_base + []) = }')
print(f'{type(user_list_base + user_list_base) = }')
# type(user_list_base) = <class '__main__.UserListBase'>
# type(user_list_base + []) = <class '__main__.UserListBase'>
# type(user_list_base + user_list_base) = <class '__main__.UserListBase'>
Как вы можете видеть, при некоторых преобразованиях исходный тип списка, построенного на основе builtins.list, может быть утерян, тогда как тип списка на основе collections.UserList сохраняется. Это важно для уверенности в сохранении пользовательских свойств списка, с которым вы работаете.