Как указать указать список ? Получение предметов не в последовательности

Я не уверен в этом методе. Я хочу создать список, где, если я попытаюсь получить доступ к элементу вне диапазона списка, список будет «зацикливаться». Пример поведения, которого я хочу достичь:

>>> musical_scale = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] >>> musical_scale[2] E >>> musical_scale[7] C >>> musical_scale[-1] B 

Думаю, я мог бы написать класс, который делает это, но я думал, что может быть более правильный способ сделать это.

4 Solutions collect form web for “Как указать указать список ? Получение предметов не в последовательности”

Используйте оператор модуля % для «возврата назад» после индексирования за конец списка

 >>> musical_scale = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] def getValue(x, l): return l[x % len(l)] >>> getValue(0, musical_scale) 'C' >>> getValue(9, musical_scale) 'E' 

Создание подкласса List будет довольно полезным способом сделать это. Что-то вроде этого, возможно:

 class modList(list): def __getitem__(self, i): if len(self) == 0: raise IndexError # Or do something else if you want, like return [] i = i % len(self) # self.__len__() works also return super(modList, self).__getitem__(i) # In Python 3, super().__getitem__(i) 

Если вы хотите сделать нарезку, это немного сложнее, но похоже. Обнаружено это при просмотре StackOverflow:

  def __getitem__(self, i): if isinstance(i, int): if len(self) == 0: raise IndexError i = i % len(self) return super(modList, self).__getitem__(i) # list.__getitem__(i) works too elif isinstance(i, slice): if len(self) == 0: return [] start = i.start % len(self) stop = i.stop % len(self) step = i.step return super(modList, self).__getItem__(slice(start, stop, step)) else: raise TypeError("invalid index") 

Хотя эта модификация среза может дать вам такую ​​ситуацию, как [3:2] , которая вернет пустой список. В основном резка жесткая, и вам нужно будет решить, как вы хотите ее реализовать, но, надеюсь, это начало.

http://www.stackoverflow.com/questions/3911483/python-slice-how-to-i-know-the-python-slice-but-how-can-i-use-built-in-slice-ob

(Спасибо @JonClements за все предложения в чате.)

EDIT: теперь у нас есть некоторые обработчики, если у вас есть пустой список. @wim предлагает создать ошибку для одиночного доступа и возвращать [] для срезов. На самом деле это зависит от вас, что вы хотите сделать, но это показалось мне разумным, вот что я включил в этот ответ.

EDIT EDIT: если вы используете Python 2.x, я считаю, что вам также необходимо переопределить __getslice__ .

Если вы хотите расширить класс списка для обработки и настройки …

 class UnsatList(list): def __getitem__(self, index): try: return list.__getitem__(self, index % len(self)) except ZeroDivisionError: raise IndexError('list assignment index out of range') def __setitem__(self, index, value): try: return list.__setitem__(self, index % len(self), value) except ZeroDivisionError: raise IndexError('list assignment index out of range') if __name__ == '__main__': test_list = UnsatList([1,2,3,4]) assert test_list[0] == 1 assert test_list[4] == 1 assert test_list[8] == 1 assert test_list[-8] == 1 test_list[4] = 5 assert test_list[0] == 5 assert test_list[4] == 5 assert test_list[8] == 5 assert test_list[-8] == 5 

Вот решение, но помните Zen of Python : Flat лучше, чем вложенный.

Вы можете написать, например:

 a = [1, [2]] a[1].append(a) 

Тогда ваш список a имеет «бесконечную глубину», и вы можете циклически перемещаться по этим двум элементам, повторяя:

 a[0] a = a[1] 

Вы не можете этого сделать, не играя с глубиной, потому что в отличие от, например, Lisp, списки Python представляют собой массивы переменной длины, а не связанные списки.

Вот несколько функций, которые можно делать автоматически:

 def loopify(a): r = b = [] for x in a: b.append(x) b.append([]) c = b b = b[1] c[1] = r return r def loopgen(a): while True: yield a[0] a = a[1] 

Затем с вашим примером:

 musical_scale = loopify(['C', 'D', 'E', 'F', 'G', 'A', 'B']) g = loopgen(musical_scale) [next(g) for i in range(20)] 

Это дает:

['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C', 'D', 'E', 'F', 'G', ' A, B, C, D, E, F, G, A,

Конечно, можно также использовать модем или отслеживать текущий индекс и пересылать его в 0 при переполнении списка. Другие ответы показывают, как это сделать.

Также обратите внимание, что метод связанных списков не допускает случайного доступа, а только последовательный доступ (таким образом, генератор выше). Если вам нужно получить доступ к списку случайно, модульная арифметика является наиболее подходящим способом.

  • Как связать аргументы с заданными значениями в функциях Python?
  • может ли пользовательский домен указывать определенный домен версии движка Google?
  • Python, для циклов, зависящих от int
  • Программно создавая переменные в Python
  • Python: сохранение строки в файл без перезаписи содержимого файла
  • GAE - Ошибка развертывания: «AttributeError: невозможно установить атрибут»
  • PyCrypto на сервере разработки Google App Engine «ImportError: невозможно импортировать имя blockalgo»
  • TypeError: объект 'module' не может быть вызван для объекта python
  •  
    Interesting Posts for Van-Lav

    В python, как проверить конец стандартных потоков ввода (sys.stdin) и сделать что-то особенное на этом

    Как я могу установить конкретную версию pip через easy-install? – Mac OS Mavericks

    Увеличьте стрелки в графике Axis3Dquiver Matplotlib

    Установка возвращаемого пути с Python sendmail для MIME-сообщения

    Передавать каждый элемент списка функции, которая принимает несколько аргументов в Python?

    winpdb не работает с python 3.3

    Как установить python-levenshtein в Windows?

    sqlite3.InterfaceError: параметр привязки ошибки 1 – возможно, неподдерживаемый тип

    Как можно определить значение #defined C для Python в модуле Cython?

    Можно ли создавать ярлыки в определенный каталог на python?

    Как создать тройной контурный сюжет в Python?

    Зачем изучать Perl, Python, Ruby, если компания использует C ++, C # или Java в качестве языка приложения?

    Как читать входной файл в Python?

    Как использовать scrapy для обхода данных из многостраничных объектов, которые реализуются javascript

    как запустить этот код в шаблоне django

    Python - лучший язык программирования в мире.