Использовать строки в качестве индексов слайсов в Python?

У меня есть отсортированный массив:

arr = ['Alexander', 'Belman', 'Erik', 'Nicholas', ... , 'Zahir']

Я хотел бы сделать что-то вроде этого:

arr['B':'M'] # ['Belman', 'Erik']

Как я могу создать класс и реализовать

__getitem__
__index__

правильно достичь этого?

Я думаю об использовании чего-то вроде

def __getitem__(self, key):
    if isinstance(key, slice):
        return [self.list[i] for i in range(key.start, key.stop)]
    return self.list[key]

но я не знаю, как индексировать строки. Как я могу создать

__index__

способ применить двоичный поиск к self.list и вернуть правильные индексы?

Всего 2 ответа


Я думаю, что вы можете обойтись такой простой реализацией, как показано ниже:

from collections import UserList

class MyList(UserList):
    def __getitem__(self, key):
        if isinstance(key, slice):
            return [e for e in self.data if key.start <= e < key.stop]
        # TODO implement the rest of the usecases and/or error handling...
        #      for now slicing with integers will miserably fail,
        #      and basic integer indexing returns None

arr = MyList(['Alexander', 'Belman', 'Erik', 'Nicholas', 'Zahir'])
print(arr['B':'M'])

который будет выводить

['Belman', 'Erik']

то же самое,

print(arr['Alex':'Er'])

будет выводить

['Alexander', 'Belman']

Обратите внимание, что я использовал key.start <= e < key.stop чтобы соответствовать поведению inclusive: exclusive ( [) ), которое используется в Python.

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


Я также публикую свое решение с помощью бинарного поиска, используя numpy

class Stock():

    def __init__(self, name, date):
        self.name = name
        self.date = np.array(date)


    def __getitem__(self, key):

        if isinstance(key, slice):
            if key.start is not None and key.stop is not None: 
                return self.date[np.searchsorted(self.date, key.start, side='left', sorter=None):np.searchsorted(self.date, key.stop, side='left', sorter=None)]
            elif key.start is not None:
                return self.date[np.searchsorted(self.date, key.start, side='left', sorter=None):]
            elif key.stop is not None:
                return self.date[:np.searchsorted(self.date, key.stop, side='left', sorter=None)]
            else:
                return self.date[:]

        i = np.searchsorted(self.date, key, side='left', sorter=None)
        if key != self.date[i]:
            raise KeyError('key: {} was not found!'.format(key))
        else:
            return self.date[i]



aapl = Stock('aapl', [񟭊',񟭌', 񟭎', 񟭐', 񟭒'])

print(aapl[񟭋':])
print(aapl[񟭎':񟭑'])
print(aapl[:񟭐'])
print(aapl[񟭊'])
print(aapl[񟭍'])

'''
[񟭌' 񟭎' 񟭐' 񟭒']
[񟭎' 񟭐']
[񟭊' 񟭌' 񟭎']
2010
Traceback (most recent call last):
  File "C:Users...Desktop...stock.py", line ##, in <module>
    print(aapl[񟭍'])
  File "C:Users...Desktop...stock.py", line ##, in __getitem__
    raise KeyError('key: {} was not found!'.format(key))
KeyError: 'key: 2013 was not found!'
'''

Есть идеи?

10000