Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何构建&x201C;矢量化&x201D;使用itertools模块的构建块?_Python_Vectorization_Itertools - Fatal编程技术网

Python 如何构建&x201C;矢量化&x201D;使用itertools模块的构建块?

Python 如何构建&x201C;矢量化&x201D;使用itertools模块的构建块?,python,vectorization,itertools,Python,Vectorization,Itertools,itertools文档的开头是以下文本: 扩展工具提供了与底层工具相同的高性能 工具集。卓越的内存性能是通过处理来保持的 元素一次一个,而不是将整个iterable放入 记忆一下子就消失了。通过链接工具,代码量保持较小 以一种功能性的风格结合在一起,有助于消除暂时性的 变量通过选择“矢量化”建筑保持高速 在使用for循环和生成器时发生阻塞 翻译开销。 问题是,应该如何构造发电机以避免开销?你能提供一些有这种开销的构造不良的块的例子吗 当我回答时,我决定问一下,在哪里我不能确切地说链(序列,[ob

itertools
文档的开头是以下文本:

扩展工具提供了与底层工具相同的高性能 工具集。卓越的内存性能是通过处理来保持的 元素一次一个,而不是将整个iterable放入 记忆一下子就消失了。通过链接工具,代码量保持较小 以一种功能性的风格结合在一起,有助于消除暂时性的 变量通过选择“矢量化”建筑保持高速 在使用for循环和生成器时发生阻塞 翻译开销。

问题是,应该如何构造发电机以避免开销?你能提供一些有这种开销的构造不良的块的例子吗


当我回答时,我决定问一下,在哪里我不能确切地说
链(序列,[obj])
是否比
链(序列,重复(obj,1))
有开销,我应该更喜欢后者。

文档文本不是关于如何构造生成器以避免开销。它解释了正确编写的
itertools
——使用代码(如示例中提供的代码)会完全避免循环和生成器,而让itertools或内置收集器(如
list
)使用迭代器

例如,
表格
示例:

def tabulate(function, start=0):
    "Return function(0), function(1), ..."
    return imap(function, count(start))
写这篇文章的非矢量化方式是:

def tabulate(function, start=0):
    i = start
    while True:
        yield function(i)
        i += 1
这个版本“招致解释器开销”,因为循环和函数调用是在Python中完成的

关于链接单个元素,可以安全地假设
chain(sequence,[obj])
将(非常)快,因为固定长度列表构造在Python中使用专门的语法和操作代码进行了优化。同样地,
chain(sequence,(obj,)
会更快,因为元组共享列表的优化,并且启动起来更小。与基准测试一样,使用
python-mtimeit
进行测量比猜测要好得多


文档引用不涉及迭代器创建中的差异,例如通过选择
repeat(foo,1)
[foo]
中的一个来显示的差异。因为迭代器只生成一个元素,所以它的使用方式没有区别。这些文档在处理可以生成数百万个元素的迭代器时谈到了处理器和内存效率。相比之下,选择创建速度更快的迭代器并不重要,因为创建策略可以随时更改。另一方面,一旦代码被设计为使用不矢量化的显式循环,以后如果不进行完全重写,就很难进行更改。

也许我应该将其表述为另一个问题。但我首先会在评论中提问。A提供
消费
生成器的代码。它有一个注释“使用以C速度使用迭代器的函数”。读了这篇评论后,我开始思考这个问题:“但是C函数每次都必须在底层迭代器上调用
next
。为什么这些调用不使用解释器开销进行处理?Python怎么知道底层迭代器是用C写的?”。不是底层迭代器用C写的,但是迭代的循环,在本例中是
collections.deque
中的循环。如果生产者和消费者都是用C语言编写的,那么实际的解释器就永远不会参与其中。(Python的对象模型仍在使用,但那是不同的。)用低级编译语言编写的循环通常会比用高级解释语言编写的循环更高效。谢谢!我的问题是关于“生产者和消费者”的案例,我举了一个只有消费者的例子,因为
consume
generator中的注释“…C速度”。所以,你回答了我真正想问的问题。唯一让我好奇的是Python是如何在
imap(函数,计数(开始))
中感知到的,
imap
知道
count
是C语言,因此绕过了解释器(因为如果事情是以一种粗糙的方式实现的,
imap
会通过解释器调用
count
上的
next
,然后解释器会将这个问题提交给
count
的C代码。顺便说一句,当这些有趣的问题和答案得到的投票数如此之少时,我总是很失望。误解仍然存在解释器是Python实现的一个组件,它遍历Python语句和表达式,如
foo+=1
bar=it.next()
,并执行它们。解释器是有效的,但它必须分离Python字节码并按照字节码的指示执行。