简体   繁体   English

是否可以在预定义的可变数据上创建python迭代器?

[英]Is it possible to create a python iterator over pre-defined mutable data?

I might be doing this wrong, if I am, let me know, but I'm curious if the following is possible: 我可能做错了,如果我是,请告诉我,但我很好奇以下是否可能:

I have a class that holds a number of dictionaries, each of which pairs names to a different set of objects of a given class. 我有一个包含许多字典的类,每个字典都将名称与给定类的不同对象集合配对。 For example: 例如:

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

My class would then hold the current items and people that are availible, and these would be subject to change as the state changes: 然后,我的班级将保留当前可用的项目和人员,随着州的变化,这些项目可能会发生变化:

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

I would like to define a iter () and next() method such that it iterates through all of the values in its attributes. 我想定义一个iter ()和next()方法,以便迭代其属性中的所有值。 My first question is whether or not this is possible. 我的第一个问题是这是否可行。 If it is, will it be able to support a situation as follows: 如果是,它是否能够支持如下情况:

I define items and people as above then: 我在上面定义了项目和人员:

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

While I feel like this would be usefull in the code I have, I don't know if it's either possible or the right approach. 虽然我觉得这对我的代码有用,但我不知道它是可能的还是正确的方法。 Everything I've read about user defined iterators has suggested that each instance of them is one use only. 我读过的关于用户定义迭代器的所有内容都表明它们的每个实例都只是一个用途。

If I understand you question correctly then adding the following method to your class should do it: 如果我理解你的问题是正确的,那么在你的类中添加以下方法应该这样做:

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

This chains together two iterators, and the ones chosen here are for the values of items and the values of people . 这种链结合在一起的两个迭代器,并在这里选择的是那些为值items和值people

To make your later code work though, you'll want to iterate over the items - the key-value pairs. 为了让你的后期代码工作,你需要迭代这些项 - 键值对。 In which case this would do it: 在这种情况下,这样做:

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

There are lots of ways to do what you want. 有很多方法可以做你想要的。 You can indeed have such a State class, and implement the iter () method ( http://docs.python.org/library/stdtypes.html ). 您确实可以拥有这样的State类,并实现iter ()方法( http://docs.python.org/library/stdtypes.html )。

You could also create a generator function: 您还可以创建生成器函数:

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

You can use itertools.chain. 你可以使用itertools.chain。 You can use list comprehensions and generator expressions. 您可以使用列表推导和生成器表达式。 Etc. 等等。

I, personally, wouldn't create the State class as you suggest, if all it is is an iterator mechanism - I'd probably use a list comprehension. 我个人不会像你建议的那样创建State类,如果它只是一个迭代器机制 - 我可能会使用列表理解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM