我想知道在Python中将可迭代对象转换为列表的这两种方式是否有区别:
using the
list()
constructor:my_list = list(my_iterable)
using a full slice:
my_list = my_iterable[:]
在实现上有什么不同吗?如果有,性能如何?Python 2与Python 3之间有任何变化吗?
当然,我意识到构造函数版本的可读性要好得多。
list(thing)
可以将一个对象转换成列表。
thing[:]
可以得到任何类型的对象。
换句话说,第二种选项仅适用于特定类型的对象(你没有提到你实际使用的哪些类型)。
编辑: thing[:]
的一个有用功能是,当它被支持时,它通常会引用“thing的所有元素”,这可以在不更改指向thing
的对象的情况下进行修改。例如:
thing[:] = [1,2,3]
即使thing
本来不是列表,也会将[1,2,3]
赋值到thing
中。
list(thing) = [1,2,3]
毫无意义,而且:
thing = [1,2,3]
使thing
引用一个新列表,而不考虑其先前的类型。
并不是所有的对象都支持切片操作,比如生成器:
(x for x in range(5))[:] # raises an error
因此,list
更为通用。 [:]
主要只是复制列表的一种方式。
[:]
之所以可行,主要是因为它是通过省略冒号前面的索引(例如[:3]
)和省略后面的索引组合而成的,这两个都是有用的。如果添加一个步长,例如[::-1]
,那么它也很有用,这是一个常见的字符串反转的方法。对于列表本身来说,[:]
并没有什么用处,但在某些情况下,它可能会稍微快一点,就像我在Padriac的答案中所评论的那样,尽管可读性通常比这种微小的优化更重要。
对于非列表对象,[:]
理论上可以根据您告诉它要执行的操作而做任何事情:
class A(object):
def __getitem__(self, item):
return 3
print A()[:] # prints 3
但你可能要避免使用这样的定义。
[:]
真的有必要吗?调用list(my_list)
也会创建一个具有不同id
的新实例,这与切片的行为相同。 - Byte CommanderIn [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
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
[:]
用于切片支持切片的任何元素,尝试在 my_iterable
不是列表时调用 list
或使用 [:]
毫无意义,因为它们基于使用对象的不同而执行非常不同的操作。
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'
range(10)
,那么结果就会被反转。[:]
避免了查找list
这个名称,所以如果你需要复制许多小列表,速度会更快。 - Alex Hall
list(thing)
,完整的切片仅在 Code Golf 中偶尔看到。所以我实际上并不真正知道切片操作符仅适用于有限的可迭代子集。感谢你的教导,我将继续像往常一样使用list(thing)
。但是,那么完整的切片操作符[:]
是否真的有必要呢?调用list(my_list)
也会创建一个具有不同id
的新实例。 - Byte Commander[:]
的主要用途是就地分配列表或数组的所有元素。例如,x = [1,2,3]; x = [4,5,6]
会为x
第二次引用创建一个完全不同的对象。但是,x = [1,2,3]; x[:] = [4,5,6]
使x
引用相同的列表对象,并覆盖其内容。这在 NumPy 中经常很有用。我已更新我的答案以反映其中一些内容。 - John Zwinck