在Python中,".append()"和"+ = []"之间有什么区别?

Nop*_*ope 118 python list concatenation

有什么区别:

some_list1 = []
some_list1.append("something")
Run Code Online (Sandbox Code Playgroud)

some_list2 = []
some_list2 += ["something"]
Run Code Online (Sandbox Code Playgroud)

Con*_*tin 157

对于您的情况,唯一的区别是性能:追加速度是其两倍.

Python 3.0 (r30:67507, Dec  3 2008, 20:14:27) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.20177424499999999
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.41192320500000079

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import timeit
>>> timeit.Timer('s.append("something")', 's = []').timeit()
0.23079359499999999
>>> timeit.Timer('s += ["something"]', 's = []').timeit()
0.44208112500000141
Run Code Online (Sandbox Code Playgroud)

一般情况下,append将向列表中添加一个项目,同时+=将右侧列表的所有元素复制到左侧列表中.

更新:性能分析

比较字节码我们可以假设append版本浪费在LOAD_ATTR+中的循环CALL_FUNCTION,+ =版本 - 在BUILD_LIST.显然BUILD_LIST胜过LOAD_ATTR+ CALL_FUNCTION.

>>> import dis
>>> dis.dis(compile("s = []; s.append('spam')", '', 'exec'))
  1           0 BUILD_LIST               0
              3 STORE_NAME               0 (s)
              6 LOAD_NAME                0 (s)
              9 LOAD_ATTR                1 (append)
             12 LOAD_CONST               0 ('spam')
             15 CALL_FUNCTION            1
             18 POP_TOP
             19 LOAD_CONST               1 (None)
             22 RETURN_VALUE
>>> dis.dis(compile("s = []; s += ['spam']", '', 'exec'))
  1           0 BUILD_LIST               0
              3 STORE_NAME               0 (s)
              6 LOAD_NAME                0 (s)
              9 LOAD_CONST               0 ('spam')
             12 BUILD_LIST               1
             15 INPLACE_ADD
             16 STORE_NAME               0 (s)
             19 LOAD_CONST               1 (None)
             22 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)

我们可以通过消除LOAD_ATTR开销来进一步提高性能:

>>> timeit.Timer('a("something")', 's = []; a = s.append').timeit()
0.15924410999923566
Run Code Online (Sandbox Code Playgroud)

  • +1:这非常有趣.无论如何我都使用append,因为它会产生更清晰的代码.但我没有意识到存在性能差异.如果有的话,我会期望追加速度慢,因为它是一个有保证的函数调用,而我推测+ =会进一步优化. (12认同)
  • 功能上也没有区别吗?例如让** a = [] **,** b = [4,5,6] **,如果您这样做** c = a.append(b)**则c将是列表的列表** [[4,5,6]] **而** c + = b **; 会得到一个简单的列表** c = [4,5,6] **。 (2认同)

DNS*_*DNS 47

在你给出的例子中,在输出方面,append和之间没有区别+=.但是append+(最初提出的问题)之间存在差异.

>>> a = []
>>> id(a)
11814312
>>> a.append("hello")
>>> id(a)
11814312

>>> b = []
>>> id(b)
11828720
>>> c = b + ["hello"]
>>> id(c)
11833752
>>> b += ["hello"]
>>> id(b)
11828720
Run Code Online (Sandbox Code Playgroud)

如你所见,append+=有相同的结果; 他们将项目添加到列表中,而不生成新列表.使用+添加两个列表并生成一个新列表.

  • 还有一个事实,即`append`添加一个条目添加到列表中,而+ =增加了许多,因为在其他的列表(即别名`extend`).但他/她已经知道了,从问题的写作方式来判断.我还缺少其他一些差异吗? (3认同)

dwc*_*dwc 39

>>> a=[]
>>> a.append([1,2])
>>> a
[[1, 2]]
>>> a=[]
>>> a+=[1,2]
>>> a
[1, 2]
Run Code Online (Sandbox Code Playgroud)

看到append将单个元素添加到列表中,这可能是任何内容.+=[]加入列表.

  • 投票,因为这是两者之间的重要区别.干得好. (2认同)

bob*_*nce 31

+ =是一项任务.当你使用它时,你真的在​​说'some_list2 = some_list2 + ['something']'.作业涉及重新绑定,因此:

l= []

def a1(x):
    l.append(x) # works

def a2(x):
    l= l+[x] # assign to l, makes l local
             # so attempt to read l for addition gives UnboundLocalError

def a3(x):
    l+= [x]  # fails for the same reason
Run Code Online (Sandbox Code Playgroud)

+ =运算符通常也应该创建一个新的列表对象,如list + list通常会:

>>> l1= []
>>> l2= l1

>>> l1.append('x')
>>> l1 is l2
True

>>> l1= l1+['x']
>>> l1 is l2
False
Run Code Online (Sandbox Code Playgroud)

但实际上:

>>> l2= l1
>>> l1+= ['x']
>>> l1 is l2
True
Run Code Online (Sandbox Code Playgroud)

这是因为Python列表实现__iadd __()来使+ =扩充赋值短路并调用list.extend().(这有点像一个奇怪的疣:它通常做你的意思,但出于令人困惑的原因.)

一般来说,如果您要追加/扩展现有列表,并且希望保持对同一列表的引用(而不是创建一个新列表),那么最好是明确的并坚持使用append()/ extend()方法.


var*_*tec 21

 some_list2 += ["something"]
Run Code Online (Sandbox Code Playgroud)

实际上是

 some_list2.extend(["something"])
Run Code Online (Sandbox Code Playgroud)

对于一个值,没有区别.文档说明:

s.append(x) 和... s[len(s):len(s)] = [x]
s.extend(x) 一样s[len(s):len(s)] = x

因此显然s.append(x)是一样的s.extend([x])


小智 8

区别在于连接将使结果列表变平,而追加将保持级别完整:

例如:

myList = [ ]
listA = [1,2,3]
listB = ["a","b","c"]
Run Code Online (Sandbox Code Playgroud)

使用append,您最终会得到一个列表列表:

>> myList.append(listA)
>> myList.append(listB)
>> myList
[[1,2,3],['a',b','c']]
Run Code Online (Sandbox Code Playgroud)

使用连接,最终得到一个平面列表:

>> myList += listA + listB
>> myList
[1,2,3,"a","b","c"]
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael 5

这里的性能测试不正确:

  1. 您不应该只运行一次配置文件.
  2. 如果比较append与+ = []的次数,则应声明追加为本地函数.
  3. 时间结果在不同的python版本上有所不同:64位和32位

例如

timeit.Timer('for x in xrange(100):app(i)','s = []; app = s.append').timeit()

可以在这里找到好的测试:http://markandclick.com/1/post/2012/01/python-list-append-vs.html