访问包装值,返回对象,迭代器或yield?

时间:2015-10-16 04:25:39

标签: python list iterator generator

我有一个班级ADT,其中有一个列表。我想通过函数访问数据来包装数据。我想出了以下访问数据的方法。 我只是想知道这些方式之间的区别,以及我应该选择哪种方式。

class ADT(object):
    """The comments is a possible replace in the feture
    """
    def __init__(self)
        #... other data...
        self.adt = [1, 2, 3, 4]
        #self.adt = {1:2, 3:4}


    #... other logic...

    def datas1(self):
        return self.adt
        #return self.adt.items()

    def datas2(self):
        return iter(self.adt)
        #return iter(self.adt.items())

    def datas3(self):
        for i in self.adt:
            yield i
        #for i in self.adt.items():
        #   yield i

用例

l = ADT()
for i in l.datas(): #use datas1 or datas2 or datas3 as datas
    #do something

2 个答案:

答案 0 :(得分:1)

让我尝试改进你的问题然后回答它。提供包装器的唯一情况是,如果您有一个可能的large and lazy序列开头:

class ADT(object):
    def __init__(self, count):
        # Count could be very large. Or maybe you want to perform a function 
        # on each value before passing it to adt, e.g.,
        # self.adt = (expensive_func(x) for x in xrange(count))  
        self.adt = xrange(count)  
        self.adt_as_list = list(self.adt)
        self.adt_as_iter = iter(self.adt)

    @property
    def adt_as_gen(self):
        for x in self.adt:
            y = yield
            yield x + y 

在这种情况下,您的选择取决于用例。

<强> 1。数据可以适合内存。使用列表。

l = ADT(10)
data = l.adt_as_list
data
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

<强> 2。数据无法容纳在内存中,但您只想循环。直接使用该属性。

l = ADT(10000)
data = l.adt
func = lambda x: x + 1
(func(x) for x in l.adt).next()
>>> 1

<强> 2。数据无法容纳在内存中,您只需要下一个值。使用迭代器。

l = ADT(10000)
data = l.adt_as_iter
data.next()
>>> 0

<强> 2。您想使用coroutine 。使用发电机。

l = ADT(10000)
data = l.adt_as_gen
data.next()
data.send(2)
>>> 2

答案 1 :(得分:0)

原样,您的完整列表已经在内存中,因为您已经设置并定义了所有实体。

  • datas1()只会引用self.lst列表对象
  • datas2()将返回一个迭代器对象
  • datas3()将返回生成器对象

有关每个内容的更多信息,请阅读文档(&#34;解释生成器和迭代器是什么&#34;不在话题)。

如果您没有计划任何额外的功能,那么您没有理由实施此功能,因为将来会出现这种情况。你为未知数过度编程。如果以后需要lst采取不同的行为,或者在其上添加功能,则可以选择扩展列表类来处理它。没有理由重写和重新填充已经存在的功能。