通常认为哪种方法更像Python/更好/更快,是相反的方法还是相反的内置函数?两者都在行动:
_list = list(xrange(4)) print _list rlist = list(reversed(_list)) print rlist _list.reverse() print _list
ijxebb2r1#
foo.reverse()实际上反转容器中的元素。reversed()实际上不反转任何东西,它只返回一个对象,该对象可用于以相反的顺序迭代容器的元素。如果这是您所需要的,则它通常比实际反转元素更快。
foo.reverse()
reversed()
bqujaahr2#
看起来有很大的不同。我真的认为是相反的。为什么重新排列列表中的值比从迭代器创建一个新的值要快?
from decorators import bench _list = range(10 ** 6) @ bench def foo(): list(reversed(_list)) @ bench def bar(): _list.reverse() foo() bar() print foo.time print bar.time
0.167278051376美元0.0122621059418
huus2vyu3#
这取决于你是否想在原处反转列表(即改变列表)。没有其他真实的的区别。经常使用reversed会产生更好的代码。
reversed
bogh5gae4#
_list.reverse()在不知道真实的性能统计信息的情况下修改列表本身,而reversed(_list)返回一个准备好以相反顺序遍历列表的迭代器,这本身就是一个很大的区别。如果这不是问题,object.reverse()对我来说似乎更容易理解,但也许你有特定的速度要求,如果reverse()不属于80%的消耗资源的软件,我不会费心(作为一般的经验法则)。
_list.reverse()
reversed(_list)
object.reverse()
reverse()
6yoyoihd5#
示例:
_list = [1,2,3] ret1 = list(reversed(_list)) ret2 = _list[::-1] #reverse order slice ret3 = _list.reverse() #no value set in ret3 print('ret1,ret2,ret3,_list:',ret1,ret2,ret3,_list) _list = [1,2,3] for x in reversed(_list): print(x)
输出:
ret1,ret2,ret3,_list: [3, 2, 1] [3, 2, 1] None [3, 2, 1] 3 2 1
oprakyz76#
如果你最终要修改迭代器中的列表,使用reversed()总是更好的,使列表不可变,并且使用不可变数据总是更好,特别是在你做函数式编程的时候。
ngynwnxp7#
在@Niklas R上扩展答案:
import timeit print('list.reverse() - real-list', timeit.timeit('_list.reverse()', '_list = list(range(1_000))')) print('list.reverse() - iterator', timeit.timeit('_list = range(1_000); list(_list).reverse()')) # can't really use .reverse() since you need to cast it first print('reversed() - real-list', timeit.timeit('list(reversed(_list))', '_list = list(range(1_000))')) print('reversed() - iterator', timeit.timeit('_list = range(1_000); list(reversed(_list))')) print('list-comprehension - real-list', timeit.timeit('_list[::-1]', '_list = list(range(1_000))')) print('list-comprehension - iterator', timeit.timeit('_list = range(1_000); _list[::-1]'))
结果:
list.reverse() - real-list 0.29828099999576807 list.reverse() - iterator 11.078685999964364 # can't really use .reverse() since you need to cast it first reversed() - real-list 3.7131450000451878 reversed() - iterator 12.048991999938153 list-comprehension - real-list 2.2268580000381917 list-comprehension - iterator 0.4313809999730438
(* 越少越好/越快 *)
bxjv4tth8#
iterator
reversed(seq)
O(1)
O(N)
[::-1]
总而言之,根据您的用例,您将不得不使用这三种目标略有不同、性能完全不同的方法之一。
8条答案
按热度按时间ijxebb2r1#
foo.reverse()
实际上反转容器中的元素。reversed()
实际上不反转任何东西,它只返回一个对象,该对象可用于以相反的顺序迭代容器的元素。如果这是您所需要的,则它通常比实际反转元素更快。bqujaahr2#
看起来有很大的不同。我真的认为是相反的。为什么重新排列列表中的值比从迭代器创建一个新的值要快?
0.167278051376美元
0.0122621059418
huus2vyu3#
这取决于你是否想在原处反转列表(即改变列表)。没有其他真实的的区别。
经常使用
reversed
会产生更好的代码。bogh5gae4#
_list.reverse()
在不知道真实的性能统计信息的情况下修改列表本身,而reversed(_list)
返回一个准备好以相反顺序遍历列表的迭代器,这本身就是一个很大的区别。如果这不是问题,
object.reverse()
对我来说似乎更容易理解,但也许你有特定的速度要求,如果reverse()
不属于80%的消耗资源的软件,我不会费心(作为一般的经验法则)。6yoyoihd5#
示例:
输出:
oprakyz76#
如果你最终要修改迭代器中的列表,使用reversed()总是更好的,使列表不可变,并且使用不可变数据总是更好,特别是在你做函数式编程的时候。
ngynwnxp7#
在@Niklas R上扩展答案:
结果:
(* 越少越好/越快 *)
bxjv4tth8#
iterator
的内置函数reversed(seq)
,反向iterator
是表示将返回该流的连续项的数据流的对象。生成该反向迭代器在时间/空间复杂度上是O(1)
,并且使用它来迭代通过列表的元素将是O(N)
,O(1)
的时间/空间复杂度,其中N是列表的长度。如果您只是想在不修改的情况下迭代反向列表,则需要使用这种方法。在这种情况下,这种方法可以提供最佳性能。_list.reverse()
就地反转列表。操作是O(N)
,O(1)
的时间/空间复杂度,因为它必须遍历列表中一半的元素才能将其反转,并且它不会将结果存储在新列表中。如果您不需要保留原始列表,并且您有几次遍历,则此方法很好/要对冲销列表的要素执行的操作,以及是否必须保存已处理的冲销列表。[::-1]
创建列表的一个新对象/a逆序复制,操作为O(N)
。O(N)
的空间/时间复杂性,因为您必须将列表的所有元素复制到新列表中,并且该新列表也将消耗与原始列表相同的空间量。如果您需要保留原始列表,并将其反向副本存储在不同的对象中以供进一步处理,那么这种方法非常有用。总而言之,根据您的用例,您将不得不使用这三种目标略有不同、性能完全不同的方法之一。