能否创建一个基于预定义可变数据的Python迭代器?

4

如果我做错了,请告诉我,但我很好奇以下是否可能:

我有一个类,其中包含许多字典,每个字典将名称与给定类的不同对象集合配对。例如:

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()方法,使其能够遍历其属性中的所有值。我的第一个问题是这是否可行。如果是,它是否能支持以下情况:
我以上述方式定义了items和people:
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
如果我正确理解了你的问题,那么将以下方法添加到你的类中应该就可以了:
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

有很多方法可以实现你想要的功能。你确实可以拥有这样一个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类 - 我可能会使用列表推导式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接