сделать структуру данных итеративной в Python - PullRequest
1 голос
/ 13 июля 2010

Итак, я немного заглянул в онлайн и просмотрел документацию, но у меня возникают проблемы с поиском, как это сделать. Я работаю над созданием приключенческой игры. У меня есть класс уровня (который содержит несколько комнат) и класс комнаты. Я хотел бы иметь возможность сделать что-то вроде следующего.

l = Level()
for room in l:
    #following code here

Мне это кажется довольно простым, однако я не могу найти правильные процедуры для реализации пользовательского итератора. Это может быть простой ответ, но я не могу найти его в Интернете. Любая помощь с благодарностью!

Ответы [ 4 ]

3 голосов
/ 13 июля 2010

Если вы определите метод-член с именем __iter__(self), Python будет знать, как выполнить его итерацию.

В этом методе я предлагаю вам использовать yield для возврата ваших данных (это называется генератором). Вы также можете вернуть список или кортеж, но это более эффективно с точки зрения памяти. Вот пример:

class Test(object):
    def __iter__(self):
        for x in range(10): 
            yield x

l = Test()
for room in l:
    print room
3 голосов
/ 13 июля 2010

Используйте __iter__ с итератором-генератором.Например,

def __iter__(self):
  for r in rooms:
    yield r

Итератор-генератор - это в основном псевдо-метод, используемый для реализации итератора.Обратите внимание, что не требуется, чтобы генератор использовал цикл for.Он может использовать любую комбинацию конструкций (если, для, в то время и т. Д.) По мере необходимости.По сути, вы просто должны помнить, что вызывающая сторона получит элементы в том порядке, в котором вы «вызываете» yield, и итерация закончится, когда метод сделает это.

См. этот раздел Pythonучебник.

1 голос
/ 14 июля 2010

В качестве альтернативы написанию генератора, метод __iter__ просто должен возвращать итератор - если у вашего объекта Level есть внутренняя структура данных, которая содержит комнаты, вы можете вернуть его итератор напрямую:

class Level(object):
    def __init__(self):
        self.rooms = []

    def __iter__(self):
        return iter(self.rooms)

Если контейнер комнат - это словарь, например, сопоставление имен комнат с объектами комнат, то вы можете получить итератор к объектам комнат с помощью метода dict.itervalues:

class Level(object):
    def __init__(self):
        self.rooms = {}

    def __iter__(self):
        return self.rooms.itervalues()
0 голосов
/ 14 июля 2010

Почему бы не использовать генератор.

>>> import timeit
>>> class Test:
    def __iter__(self):
        for i in range(10):
            yield i

>>> t1 = lambda: [k for k in Test()]
>>> timeit.timeit(t1)
3.529460948082189


>>> def test2():
    for i in range(10):
        yield i

>>> t2 = lambda: [k for k in test2()]
>>> timeit.timeit(t2)
3.171831107365392
...