【问题标题】:Python List Indexing or Appending?Python列表索引或附加?
【发布时间】:2015-08-03 20:10:46
【问题描述】:

就处理时间、内存使用以及一般来说最好的编程选项而言,向列表添加值的最佳方式是什么。

list = []

for i in anotherArray:
    list.append(i)

或

list = range(len(anotherArray))

for i in list:
    list[i] = anotherArray[i]

考虑到 anotherArray 是一个元组数组。 (这只是一个简单的例子)

【问题讨论】:

标签: python list indexing append


【解决方案1】:

这真的取决于您的用例。这里没有通用答案,因为这取决于您要做什么。

在您的示例中,您似乎只是在尝试创建数组的副本,在这种情况下,最好的方法是使用副本:

from copy import copy    
list = copy(anotherArray)

如果您尝试将数组转换为另一个数组,则应使用列表推导。

list =  [i[0] for i in anotherArray]  # get the first item from tuples in anotherArray

如果您尝试同时使用索引和对象,则应使用枚举:

for i, j in enumerate(list)

这比你的第二个例子好得多。

您还可以使用生成器、lambas、地图、过滤器等。所有这些可能性之所以存在,是因为它们都因不同的原因而“更好”。 python 的作者在“一种正确的方式”上相当大,所以相信我,如果有一种通用的方式总是更好,那就是 python 中存在的唯一方式。


编辑:计算元组交换的一些性能结果,结果如下:

comprehension: 2.682028295999771
enumerate: 5.359116118001111
for in append: 4.177091988000029
for in indexes: 4.612594166001145

如您所知,理解通常是最好的选择。使用枚举是昂贵的。 以下是上述测试的代码:

from timeit import timeit

some_array = [(i, 'a', True) for i in range(0,100000)]

def use_comprehension():
    return [(b, a, i) for i, a, b in some_array]

def use_enumerate():
    lst = []
    for j, k in enumerate(some_array):
        i, a, b = k
        lst.append((b, a, i))
    return lst

def use_for_in_with_append():
    lst = []
    for i in some_array:
        i, a, b = i
        lst.append((b, a, i))
    return lst

def use_for_in_with_indexes():
    lst = [None] * len(some_array)
    for j in range(len(some_array)):
        i, a, b = some_array[j]
        lst[j] = (b, a, i)
    return lst

print('comprehension:', timeit(use_comprehension, number=200))
print('enumerate:', timeit(use_enumerate, number=200))
print('for in append:', timeit(use_for_in_with_append, number=200))
print('for in indexes:', timeit(use_for_in_with_indexes, number=200))

编辑2:

有人向我指出,OP 只是想知道“索引”和“附加”之间的区别。实际上,它们也用于两个不同的用例。索引用于替换对象,而附加用于添加。但是,在列表开始为空的情况下,追加总是更好,因为索引具有最初创建列表的开销。从上面的结果可以看出,索引速度稍慢,主要是因为你必须创建第一个列表。

【讨论】:

  • 我已经提到了枚举,这绝对是包含操作的最佳选择。
  • @Malik 我不同意,列表推导在大多数情况下性能更高,更 Python 化。
  • 这对我来说是一个非常糟糕的例子......我认为这里没有人理解这个问题......它真的在标题中。我问的是“索引或追加”,而不是“什么是最好的类型”......但无论如何,知道在每种情况下什么是最好的会很有帮助。
  • @Rayden 您的评论实际上帮助我理解了这个问题。稍后我会在这里更新答案。
  • @Nick 谢谢这正是我想要的。由于我对 numpy 数组的经验,我认为 append 会花费更多时间,但我刚刚研究过,人们说它们的工作方式与列表不同,所以对于列表,最好使用 append 或者如果我没有很多操作要做,我会使用列表推导。
【解决方案2】:

实际上我想说最好的是 index loops 和 value loops 与枚举的组合:

for i, j in enumerate(list): # i is the index, j is the value, can't go wrong

【讨论】:

  • 因此您可以在需要时使用其中一种。
  • 对,我一直在研究它,我认为它很有用,但我认为这里没有人理解这个问题......它真的在标题中。我问的是“索引或追加”,而不是“什么是最好的类型”......
  • 追加不会花费更多时间吗?在某种程度上,当您不断更改列表大小时,您必须每次都去获取所需的内存。当你有一个固定的大小时,它总是不变的,你只需要担心改变里面的值。
  • 它们是两个完全不同的操作。 Append 将一个项目添加到末尾。索引会更改给定点的值。一个并不比另一个好,它们是完全不同的操作。
【解决方案3】:

最好的方法是列表理解:

my_list=[i for i in anotherArray]

但是根据您的问题,您可以使用生成器表达式(当您只想循环遍历您的项目并且不需要使用某些列表方法(例如 indexing 或 len 或... )

my_list=(i for i in anotherArray)

【讨论】:

  • 是的,但是当我在每次迭代中进行操作时,我很担心,这只是为了一个简单的副本。我应该更好地解释自己。
  • @Rayden 你说的操作是什么意思?当您可以访问迭代中的每个项目时,您可以对其进行任何操作!
  • @Rayden 你的意思是就地操作吗?
  • 我的意思是喜欢使用 ifs 和 elses(我知道你可以在列表理解中但它受到更多限制),进行计算等。
  • @Rayden 在那种情况下它可能有很多场景!这一切都取决于你的问题!因为你可以使用很多 python 的工具来让你的代码更高效、更快!
猜你喜欢
  • 2015-11-29
  • 2018-08-23
  • 1970-01-01
  • 2020-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2014-05-02
相关资源
最近更新 更多