Python 从迭代器获取唯一值的快速方法
众所周知,迭代器显示出比普通列表理解更好的性能:Python 从迭代器获取唯一值的快速方法,python,performance,python-2.7,iterator,Python,Performance,Python 2.7,Iterator,众所周知,迭代器显示出比普通列表理解更好的性能: In [8]: from random import random In [10]: %timeit [random() for i in range(10000000)] 1 loops, best of 3: 883 ms per loop In [11]: %timeit (random() for i in range(10000000)) 10 loops, best of 3: 176 ms per loop 但是,当我尝试从迭
In [8]: from random import random
In [10]: %timeit [random() for i in range(10000000)]
1 loops, best of 3: 883 ms per loop
In [11]: %timeit (random() for i in range(10000000))
10 loops, best of 3: 176 ms per loop
但是,当我尝试从迭代器获取唯一值时,性能增益消失:
In [12]: %timeit set([random() for i in range(10000000)])
1 loops, best of 3: 5.06 s per loop
In [13]: %timeit set((random() for i in range(10000000)))
1 loops, best of 3: 5.02 s per loop
我想知道是否有快速和通用的方法来获取可编辑对象的唯一值?(我知道,但我经常需要处理字符串)。正如@georg
[11]所提到的那样,
很快,因为它基本上什么都不做
如果您使用的是Python 2,range()
会创建一个列表,而xrange()
不会。这使得:
In [1]: from random import random
In [2]: timeit set([random() for i in xrange(10000000)])
1 loops, best of 3: 6.11 s per loop
In [3]: timeit set(random() for i in xrange(10000000))
1 loops, best of 3: 5.61 s per loop
这显示了一点时间增益。无论如何,[3]
比[2]
的主要增益当然是内存增益
要回答您的问题,使用
set()
并确保不在两者之间创建列表是从生成器中获取唯一值的最佳(也是最具python风格的)方法。虽然set
将保证唯一性,但它会破坏顺序,从而减少序列的随机性,而且你不能保证拥有你生成的那么多的项目。另一种方法是首先确保生成的所有项都是唯一的,如所示:
这是因为它不仅是可索引的,而且遵循序列协议(可索引且具有长度)。这个问题涉及到“为一个iterable对象获取唯一的值”,它并没有很好地描述所示示例的功能。也许,如果我们知道任务是什么,就可以找到一个更合适的答案
[11]
测试并不是你想象的那样。它只是定义了一个生成器,而没有使用它——这就是为什么它如此快速的原因。@georg,好的。因此,[12]
和[13]
测试的相等性是一致的结果,不是吗?没有办法改善吗?对。如果你消费所有的东西,所有的iterables(gens、LC、List)都会有相当的性能。发电机是内存节省器,不是速度助推器。@georg,谢谢你的澄清@georg很在行——当您不需要同时使用所有元素时,迭代器(以及itertools
中方便的功能)的好处就来了。您可以创建一个一次生成一个数字的xrange(10000000)
,而不是用列表range(10000000)
填充内存块。缺点是不能随意返回或索引,但在许多情况下,逐元素工作是最好的方法。
sample(xrange(10000000), 60)