Python:将iterable转换为list:';列表(x)和#x27;与全切片相比';x[:]和#x27;
我想知道在Python中将iterable转换为list的这两种方法是否有任何区别:Python:将iterable转换为list:';列表(x)和#x27;与全切片相比';x[:]和#x27;,python,list,slice,Python,List,Slice,我想知道在Python中将iterable转换为list的这两种方法是否有任何区别: 使用list()构造函数: my_list = list(my_iterable) 使用完整切片: my_list = my_iterable[:] 在实施过程中是否存在差异?如果是,性能如何?Python2和Python3之间有什么变化吗 当然,我意识到构造函数版本的可读性更好。list(thing)提供了一个列表 thing[:]可以给你它想要的任何类型 换句话说,第二个选项只适用于特定类型(您
- 使用
构造函数:list()
my_list = list(my_iterable)
- 使用完整切片:
my_list = my_iterable[:]
list(thing)
提供了一个列表
thing[:]
可以给你它想要的任何类型
换句话说,第二个选项只适用于特定类型(您没有提到实际使用的类型)
编辑:thing[:]
的一个有用特性是,当它被支持时,通常会导致引用“thing的所有元素”,可以在不更改对象thing
指向的情况下对其进行修改。例如:
thing[:] = [1,2,3]
将[1,2,3]
分配到内容
的上方,即使这本身不是一个列表。鉴于:
list(thing) = [1,2,3]
这是胡说八道,而且:
thing = [1,2,3]
使
事物
引用新列表,而不管其以前的类型。并非所有事物都支持切片,例如生成器:
(x for x in range(5))[:] # raises an error
因此,列表
更一般[:]
是一种复制列表的方法
之所以可以使用[:]
,主要原因是当您将冒号前的索引省略(例如[:3]
)和冒号后的索引省略组合在一起时,这两种方法都很有用。如果添加一个步骤也很有用,例如,[::-1]
是反转字符串的常用方法<代码>[:]本身对列表不是很有用,但在某些情况下它会稍微快一点,正如我对Padriac答案的评论,尽管可读性通常比这种微观优化更重要
对于非列表,[:]
理论上可以根据您告诉它的内容执行任何操作:
class A(object):
def __getitem__(self, item):
return 3
print A()[:] # prints 3
但是您可能应该避免这样的定义。我认为我的iterable始终是一个列表或列表的子类,或者这两种方法可能产生完全不同的结果:
在python2中,调用列表比切片稍快:
In [2]: l = list(range(1000000))
In [3]: timeit l[:]
100 loops, best of 3: 10.8 ms per loop
In [4]: timeit list(l)
100 loops, best of 3: 9.45 ms per loop
Python3的结果非常相似:
In [1]: l = list(range(1000000))
In [2]: timeit list(l)
100 loops, best of 3: 9.54 ms per loop
In [3]: timeit l[:]
100 loops, best of 3: 10.6 ms per loop
[:]
用于从任何支持切片的元素中切片所有元素,尝试比较调用list
或使用[:]
时,如果my_iterable
是一个列表,则没有实际意义,因为它们都会根据您使用它们的内容执行非常不同的操作
In [2]: i = (1,2,3,4,5)
In [3]: list(i)
Out[3]: [1, 2, 3, 4, 5]
In [4]: i[:]
Out[4]: (1, 2, 3, 4, 5)
In [5]: i = "hello world"
In [6]: list(i)
Out[6]: ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
In [7]: i[:]
Out[7]: 'hello world'
我通常总是使用
list(thing)
,完整的片段只是我偶尔在CodeGolf上看到的。因此,我实际上并不知道切片操作符只对有限的iterables子集起作用。感谢您的课程,我将继续并一如既往地使用list(thing)
。但是真的需要完整的切片操作符吗?调用list(my_list)
也会创建一个具有不同id
@ByteCommander的新实例:[:]
在现实世界中的主要用途是将列表或数组的所有元素指定到位。例如,x=[1,2,3];x=[4,5,6]
为x
创建了一个完全不同的对象,以便第二次引用。但是x=[1,2,3];x[:]=[4,5,6]
使x
引用同一列表对象,并覆盖内容。例如,这在NumPy中经常很有用。我更新了我的答案来反映其中的一些。哦,酷!我还没听说过分配一个切片。感谢您的这些见解。那么是否真的需要完整的切片操作符[:]
?调用list(my_list)
也会创建一个具有不同id
的新实例,这与切片的行为相同。如果将开始更改为range(10)
,则结果会颠倒[:]
避免查找名称列表
,因此,如果您必须复制多个小列表,则会更快。