Python: list comprehension的机制

17 浏览
0 Comments

Python: list comprehension的机制

当在for循环上下文中使用列表推导或in关键字时,即:\n

for o in X:
    对o执行某些操作

\n或者\n

l=[o for o in X]

\n

    \n

  • in的机制是如何工作的?
  • \n

  • X中调用了哪些函数或方法?
  • \n

  • 如果X可以符合多个方法,那么优先级是什么?
  • \n

  • 如何编写一个高效的X,以便列表推导运行快速?
  • \n

0
0 Comments

Python: 列表推导背后的机制

在回答问题的评论中,我可以说在这种情况下阅读源代码并不是最好的方法。负责执行编译代码的代码(ceval.c)对于第一次看到Python源代码的人来说似乎不是很冗长。下面是代表for循环中迭代的代码片段:

TARGET(FOR_ITER)
    /* before: [iter]; after: [iter, iter()] *or* [] */
    v = TOP();
    /*
      Here tp_iternext corresponds to next() in Python
    */
    x = (*v->ob_type->tp_iternext)(v); 
    if (x != NULL) {
        PUSH(x);
        PREDICT(STORE_FAST);
        PREDICT(UNPACK_SEQUENCE);
        DISPATCH();
    }
    if (PyErr_Occurred()) {
        if (!PyErr_ExceptionMatches(
                        PyExc_StopIteration))
            break;
        PyErr_Clear();
    }
    /* iterator ended normally */
    x = v = POP();
    Py_DECREF(v);
    JUMPBY(oparg);
    DISPATCH();

要找出这里实际发生了什么,您需要深入研究一堆其他文件,它们的冗长程度也不好。因此,我认为在这种情况下,文档和像SO这样的网站是首先要去的地方,而源代码仅用于检查未覆盖的实现细节。

0
0 Comments

Python中的列表推导是一种用于创建新的列表的简洁且强大的方法。然而,有时候我们可能会遇到一个问题,即"Python: the mechanism behind list comprehension"。这个问题的原因是X必须是可迭代的,也就是说X必须实现__iter__()方法来返回一个迭代器对象;迭代器对象必须实现next()方法,在每次调用时返回下一个项目,或者如果没有下一个项目则引发StopIteration异常。列表、元组和生成器都是可迭代的。需要注意的是,普通的for循环也使用相同的机制。迭代器也必须实现__iter__()方法,尽管它们可以只返回对自身的引用。另外,X还可以实现__getitem__()方法来实现可迭代性。为了解决这个问题,我们可以确保X是可迭代的,或者实现__getitem__()方法来实现可迭代性。

0
0 Comments

Python中的列表推导是一种简洁而强大的语法,可以在一个表达式中生成一个新的列表。然而,有时会出现TypeError: 'Nothing' object is not iterable的错误。这个问题的出现是因为在for循环和列表推导中,Python会调用iter()函数来对迭代对象进行迭代。iter()函数会检查对象是否实现了__iter__方法或者__getitem__方法,如果实现了其中一个,则返回一个可迭代对象。如果两个方法都实现了,优先使用__iter__方法。如果两个方法都没有实现,则会出现TypeError: 'Nothing' object is not iterable的错误。

为了解决这个问题,我们可以实现一个类,其中包含__getitem__方法来进行迭代操作。例如,可以实现一个名为GetItem的类,其中包含一个data属性和一个__getitem__方法。然后,可以通过创建一个GetItem的实例,并在列表推导中使用它来进行迭代操作。

另一种解决方法是实现一个类,其中包含__iter__方法来返回一个迭代器。例如,可以实现一个名为TheIterator的类,它包含一个data属性、一个index属性和一个next方法。在__iter__方法中,我们将自身作为迭代器返回。然后,可以创建一个Iter的实例,并在列表推导中使用它来进行迭代操作。

另外,我们还可以将两种方法结合起来。可以实现一个名为CombinedIter的类,其中包含一个data属性和一个__iter__方法。在__iter__方法中,我们将index属性初始化为-1,并返回自身作为迭代器。然后,通过实现next方法来进行迭代操作。

除了以上方法,还可以使用yield关键字和生成器来实现迭代器。可以实现一个名为Generator的类,其中包含一个data属性和一个__iter__方法。在__iter__方法中,我们使用yield关键字来生成迭代值。

总结起来,解决TypeError: 'Nothing' object is not iterable的方法有多种。我们可以实现一个包含__getitem__方法的类、一个包含__iter__方法的类、一个同时包含__getitem__和__iter__方法的类,或者使用yield关键字和生成器来实现迭代器。其中,使用生成器是最简单和高效的方法。

这篇文章介绍了解决TypeError: 'Nothing' object is not iterable的问题的几种方法,包括实现不同的类以及使用yield和生成器。这些方法可以帮助我们在使用列表推导时避免出现TypeError错误,并能够高效地进行迭代操作。

0