Python:列表理解背后的机制 [英] Python: the mechanism behind list comprehension

查看:96
本文介绍了Python:列表理解背后的机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在for循环上下文中使用列表理解或in关键字时,即:

When using list comprehension or the in keyword in a for loop context, i.e:

for o in X:
    do_something_with(o)

l=[o for o in X]

  • in背后的机制如何工作?
  • 它调用X中的哪些函数\方法?
  • 如果X可以遵循多种方法,那么优先级是多少?
  • 如何编写高效的X,以便快速理解列表?
    • How does the mechanism behind in works?
    • Which functions\methods within X does it call?
    • If X can comply to more than one method, what's the precedence?
    • How to write an efficient X, so that list comprehension will be quick?
    • 推荐答案

      答案是正确的.

      for在for循环和列表推导中都在X上调用iter().如果X具有__iter__方法或__getitem__方法,则iter()将返回可迭代.如果两者都实现,则使用__iter__.如果没有,您将得到TypeError: 'Nothing' object is not iterable.

      for, both in for loops and list comprehensions, calls iter() on X. iter() will return an iterable if X either has an __iter__ method or a __getitem__ method. If it implements both, __iter__ is used. If it has neither you get TypeError: 'Nothing' object is not iterable.

      这实现了__getitem__:

      class GetItem(object):
          def __init__(self, data):
              self.data = data
      
          def __getitem__(self, x):
              return self.data[x]
      

      用法:

      >>> data = range(10)
      >>> print [x*x for x in GetItem(data)]
      [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
      

      这是实现__iter__的示例:

      class TheIterator(object):
          def __init__(self, data):
              self.data = data
              self.index = -1
      
          # Note: In  Python 3 this is called __next__
          def next(self):
              self.index += 1
              try:
                  return self.data[self.index]
              except IndexError:
                  raise StopIteration
      
          def __iter__(self):
              return self
      
      class Iter(object):
          def __init__(self, data):
              self.data = data
      
          def __iter__(self):
              return TheIterator(data)
      

      用法:

      >>> data = range(10)
      >>> print [x*x for x in Iter(data)]
      [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
      

      如您所见,您既需要实现一个迭代器,又需要返回迭代器的__iter__.

      As you see you need both to implement an iterator, and __iter__ that returns the iterator.

      您可以将它们组合在一起:

      You can combine them:

      class CombinedIter(object):
          def __init__(self, data):
              self.data = data
      
          def __iter__(self):
              self.index = -1
              return self
      
          def next(self):
              self.index += 1
              try:
                  return self.data[self.index]
              except IndexError:
                  raise StopIteration
      

      用法:

      >>> well, you get it, it's all the same...
      

      但是,一次只能有一个迭代器. 好的,在这种情况下,您可以这样做:

      But then you can only have one iterator going at once. OK, in this case you could just do this:

      class CheatIter(object):
          def __init__(self, data):
              self.data = data
      
          def __iter__(self):
              return iter(self.data)
      

      但这是作弊,因为您只是在重用list__iter__方法. 一种更简单的方法是使用yield,并将__iter__用作生成器:

      But that's cheating because you are just reusing the __iter__ method of list. An easier way is to use yield, and make __iter__ into a generator:

      class Generator(object):
          def __init__(self, data):
              self.data = data
      
          def __iter__(self):
              for x in self.data:
                  yield x
      

      这是我推荐的方式.简单高效.

      这篇关于Python:列表理解背后的机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆