Как при превышении индексом длины списка запустить проход по списку заново?

Делаю программу на python, и возникла проблема. Есть список, например:

mylist = ['a', 'b']

, и, если индекс списка больше длины самого списка, то он должен обойти список ещё раз а не вывести ошибку. например:

mylist = ['a', 'b']
print(mylist[3])

Как сделать такое в python?


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

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

Для этого нужно сделать так, чтобы index был меньше длины списка. Это делается взятием остатка.

mylist = ['a', 'b']
index = input('Индекс')
try:
    index = int(index)
except:
    print('Вы ввели не число!')
else:
    print(mylist[index % len(mylist)])
→ Ссылка
Автор решения: Vitalizzare ушел в монастырь

Если целью является унификация обращений к списку без оглядки на индекс, то можно создать новый класс с опорой на 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 сохраняется. Это важно для уверенности в сохранении пользовательских свойств списка, с которым вы работаете.

→ Ссылка