- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在回答问题时Clunky calculation of differences between an incrementing set of numbers, is there a more beautiful way? ,我提出了两种解决方案,一种使用 List Comprehension
,另一种使用 itertools.starmap .
对我来说,list comprehension
语法看起来更清晰、更易读、不那么冗长而且更符合 Pythonic。但仍然是starmap在 itertools 中很好用,我想知道,必须有它的原因。
我的问题是什么时候 starmap
比 List Comprehension
更受欢迎?
注意 如果它是样式问题,那么它肯定与应该有一个——最好只有一个——显而易见的方法来做到这一点相矛盾。
头对头比较
可读性很重要。 --- LC
这又是一个感知问题,但对我而言,LC
比 starmap
更具可读性。要使用 starmap
,您需要导入 operator
,或者定义 lambda
或一些显式的 multi-variable
函数和尽管如此,从 itertools
额外导入。
性能 --- LC
>>> def using_star_map(nums):
delta=starmap(sub,izip(nums[1:],nums))
return sum(delta)/float(len(nums)-1)
>>> def using_LC(nums):
delta=(x-y for x,y in izip(nums[1:],nums))
return sum(delta)/float(len(nums)-1)
>>> nums=[random.randint(1,10) for _ in range(100000)]
>>> t1=Timer(stmt='using_star_map(nums)',setup='from __main__ import nums,using_star_map;from itertools import starmap,izip')
>>> t2=Timer(stmt='using_LC(nums)',setup='from __main__ import nums,using_LC;from itertools import izip')
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=1000)/100000)
235.03 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=1000)/100000)
181.87 usec/pass
最佳答案
我通常看到的区别是 map()
/starmap()
最适合您实际上只是对列表中的每个项目调用一个函数的情况。在这种情况下,它们更清晰一些:
(f(x) for x in y)
map(f, y) # itertools.imap(f, y) in 2.x
(f(*x) for x in y)
starmap(f, y)
一旦你开始需要加入 lambda
或 filter
,你应该切换到列表 comp/generator 表达式,但在它是单一函数,对于列表理解的生成器表达式来说,语法感觉非常冗长。
它们是可互换的,如果有疑问,请坚持使用生成器表达式,因为它通常更具可读性,但在简单情况下 (map(int, strings)
, starmap(Vector, points)
) 使用 map()
/starmap()
有时可以使内容更易于阅读。
我认为 starmap()
更具可读性的示例:
from collections import namedtuple
from itertools import starmap
points = [(10, 20), (20, 10), (0, 0), (20, 20)]
Vector = namedtuple("Vector", ["x", "y"])
for vector in (Vector(*point) for point in points):
...
for vector in starmap(Vector, points):
...
对于map()
:
values = ["10", "20", "0"]
for number in (int(x) for x in values):
...
for number in map(int, values):
...
python -m timeit -s "from itertools import starmap" -s "from operator import sub" -s "numbers = zip(range(100000), range(100000))" "sum(starmap(sub, numbers))"
1000000 loops, best of 3: 0.258 usec per loop
python -m timeit -s "numbers = zip(range(100000), range(100000))" "sum(x-y for x, y in numbers)"
1000000 loops, best of 3: 0.446 usec per loop
构造一个namedtuple
:
python -m timeit -s "from itertools import starmap" -s "from collections import namedtuple" -s "numbers = zip(range(100000), reversed(range(100000)))" -s "Vector = namedtuple('Vector', ['x', 'y'])" "list(starmap(Vector, numbers))"
1000000 loops, best of 3: 0.98 usec per loop
python -m timeit -s "from collections import namedtuple" -s "numbers = zip(range(100000), reversed(range(100000)))" -s "Vector = namedtuple('Vector', ['x', 'y'])" "[Vector(*pos) for pos in numbers]"
1000000 loops, best of 3: 0.375 usec per loop
在我的测试中,我们讨论的是使用简单函数(没有 lambda
),starmap()
比等效的生成器表达式更快。自然地,性能应该让位于可读性,除非它已被证明是瓶颈。
lambda
如何扼杀任何性能提升的示例,与第一组中的示例相同,但使用 lambda
而不是 operator.sub()
:
python -m timeit -s "from itertools import starmap" -s "numbers = zip(range(100000), range(100000))" "sum(starmap(lambda x, y: x-y, numbers))"
1000000 loops, best of 3: 0.546 usec per loop
关于python - 什么时候 starmap 比 `List Comprehension` 更受欢迎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10448486/
我有一个可以并行运行多个查询的函数,但是我在使用 multiprocessing 运行我的函数时遇到了一些麻烦。我有这段代码: def run(args): query, cursor = a
我在尝试使用 multiprocessing.Pool.starmap 时遇到了一个奇怪的错误。重现错误所需的最少代码在这里: from multiprocessing import Pool # I
最初,对于我使用的代码,Pool.map 足以对我的代码进行线程化,因为只有一个参数(一个可迭代的)作为参数传入我的函数。现在,我需要将多个参数传递给该函数,但我在使用 Pool.starmap 时遇
是否有类似于 pools.starmap 的函数可以与字典列表一起使用? 代替 :pools.starmap(func, iterable_of_tuple) 你将会拥有:pools.starmapd
我正在使用多处理pool.starmap函数。我发现一个奇怪的问题。 from multiprocessing import Pool p = multiprocessing.Pool() NODE
我正在尝试一些网页抓取。我正在将包含 URL 的列表传递给 pool.starmap ,但我遇到了参数错误。显示我的代码的简化版本: 有人可以帮我解决这个问题吗?对不起,如果我做了一些愚蠢的事情。 f
我有一个使用多处理库来计算一些东西的程序。大约有 10K 个输入需要计算,每个输入需要 0.2 秒到 10 秒的时间。 我当前的方法使用池: # Inputs signals = [list(s) f
这个starmap示例程序按预期工作: import multiprocessing def main(): pool = multiprocessing.Pool(10) param
假设我有这两种方法来完成相同的任务: from multiprocessing import Pool pool = Pool(4) def func(*args): # do some sl
关于 this post 的第二个答案, 我试过下面的代码 from multiprocessing import Pool import numpy as np from itertools imp
所以我创建了一个多处理列表(特别是 multiprocessing.Pool().starmap())并希望减少其内存大小。名单如下: import sys import numpy as np fr
在回答问题时Clunky calculation of differences between an incrementing set of numbers, is there a more beau
我正在使用 Pool 对我的程序进行多线程处理,使用 starmap 来传递参数。 我被卡住了,因为我似乎无法找到一种方法来传递 kwargs 以及我在 starmap 函数中传递的 zip 数组。
我是一名优秀的程序员,十分优秀!