Можно ли создать итератор Python для предварительно определенных изменяемых данных? - PullRequest
4 голосов
/ 31 мая 2010

Возможно, я делаю это неправильно, если да, дайте мне знать, но мне любопытно, возможно ли следующее:

У меня есть класс, который содержит несколько словарей, каждый из которых объединяет имена в разные наборы объектов данного класса. Например:

items = {"ball" : ItemInstance1, "sword" : ItemInstance2}
people = {"Jerry" : PersonInstance1, "Bob" : PersonInstance2, "Jill" : PersonInstance3}

Мой класс будет содержать текущие предметы и людей, которые доступны, и они могут изменяться при изменении состояния:

Class State:
    def __init__(self, items, people):
        self.items = items
        self.people = people

Я бы хотел определить метод iter () и next (), чтобы он перебрал все значения в своих атрибутах. Мой первый вопрос: возможно ли это? Если да, сможет ли он поддержать ситуацию следующим образом:

Я определяю предметы и людей, как указано выше:

state = State(items, people)
for names, thing in state:
    print name + " is " + thing.color

items[cheese] = ItemInstance3
for names, thing in state:
    print name + " weighs " + thing.weight

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

Ответы [ 2 ]

2 голосов
/ 31 мая 2010

Если я правильно понимаю ваш вопрос, то добавление следующего метода в ваш класс должно сделать это:

def __iter__(self):
    import itertools
    return itertools.chain(self.items.itervalues(), self.people.itervalues())

Это объединяет два итератора, и выбранные здесь значения для значений items и значений people.

Чтобы ваш более поздний код работал, вам нужно будет перебирать элементы - пары ключ-значение. В этом случае это будет сделано:

def __iter__(self):
    import itertools
    return itertools.chain(self.items.iteritems(), self.people.iteritems())
1 голос
/ 31 мая 2010

Есть много способов сделать то, что вы хотите. Вы действительно можете иметь такой класс State и реализовать метод iter () (http://docs.python.org/library/stdtypes.html).

).

Вы также можете создать функцию генератора:

   def iterate_two(l1, l2):
      for k in l1:
         yield k, l1[k]
      for k in l2:
         yield k, l2[k]

Вы можете использовать itertools.chain. Вы можете использовать списочные выражения и выражения генератора. И т.д.

Лично я бы не стал создавать класс State, как вы предлагаете, если бы все это был механизм итератора - я бы, вероятно, использовал понимание списка.

...