当前位置:  开发笔记 > 编程语言 > 正文

Python 2,在简单的情况下映射不等同于列表推导; 长度依赖

如何解决《Python2,在简单的情况下映射不等同于列表推导;长度依赖》经验,为你挑选了0个好方法。

在python 2中,内置函数map似乎调用__len__时长度被覆盖.这是否正确 - 如果是这样,为什么我们计算迭代的长度来映射?Iterables不需要覆盖长度(例如),并且即使长度没有被iterable预定义,map函数也能工作.

地图在这里定义; 它确实指定在传递多个iterables的情况下存在与长度相关的功能.然而,

我对只传递一个iterable的情况感兴趣

即使传递了多个迭代(不是我的问题),显然检查长度似乎是一个奇怪的设计选择,而不是只是迭代直到你用完然后返回 None

我因为根据几个很关注1 2极高upvoted的问题,

map(f, iterable)

基本上相当于:

[f(x) for x in iterable]

但我遇到了一些简单的例子.

例如

class Iterable:

    def __iter__(self):
        self.iterable = [1,2,3,4,5].__iter__()
        return self

    def next(self):
        return self.iterable.next()

   #def __len__(self):
   #     self.iterable = None
   #    return 5


def foo(x): return x

print( [foo(x) for x in Iterable()] )
print( map(foo,Iterable()) )

表现得如此,但如果你取消超载的话len,它就不会.

在这种情况下,它会引发AttributeError,因为iterable是None.虽然单位行为是愚蠢的,但我认为在len的规范中没有要求不变性.当然,最好不要在调用中修改状态len,但原因不应该是因为内置函数中存在意外行为.在更现实的情况下,我的len功能可能只是很慢,我不希望担心它被调用map,或者它可能不是线程安全的等等.


实施依赖?

由于map是内置函数,它可能在规范之外具有特定于实现的特性,但是cpython在bltinmodule.c的第918行实现它,它确实指出:

/* Do a first pass to obtain iterators for the arguments, and set len
 * to the largest of their lengths.
 */

然后调用_PyObject_LengthHint,在Object/abstract.c中定义,实际上似乎寻找覆盖len.这并没有向我澄清这是否只是依赖于实现,或者我是否缺少某种map有意识地根据我的直觉寻找迭代长度的理由.


(注意我没有在python 3中测试过这个,这就是为什么我指定了python 2.在python3中,map返回一个生成器,所以至少我的一些声明不是真的)

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有