Python: 理解append和extend的区别

8

以下代码在当前状态下无法运行。然而,如果我将sum_vec.extend( vec1[i] + vec2[i] )更改为sum_vec.append( vec1[i] + vec2[i] ),它就可以正确运行。我了解append和extend的基本区别,但我不理解为什么如果我使用extend代码就无法工作。

def addVectors(v1, v2):

    vec1 = list(v1)
    vec2 = list(v2)
    sum_vec = []
    vec1_len = len(vec1)
    vec2_len = len(vec2)
    min_len = min( vec1_len, vec2_len )

    # adding up elements pointwise
    if vec1_len == 0 and vec2_len == 0:
        return sum_vec
    else:
        for i in xrange(0, min_len):
            sum_vec.extend( vec1[i] + vec2[i] )

    # in case one vector is longer than the other
    if vec1_len != vec2_len:
        if vec1_len > vec2_len:
            sum_vec.extend( vec1[min_len : vec1_len] )
        else:
            sum_vec.extend( vec2[min_len : vec2_len] ) 
    print sum_vec
    return sum_vec

v1 = [1,3,5]
v2 = [2,4,6,8,10]
addVectors(v1,v2)

你看过这两个操作后 sum_vec 版本之间的差异吗? "不起作用" 到底是什么意思 - 错误?意外输出? - jonrsharpe
5个回答

19

正如其他人指出的那样,extend 接受一个可迭代对象(比如列表、元组或字符串),并将可迭代对象中的每个元素一个接一个地添加到列表中,而 append 则将其参数作为单个项添加到列表的末尾。需要注意的关键点是,extend 是调用多次 append 的更高效版本。

a = [1,2]
b = [1,2]

a.extend([3, 4])
for x in [3, 4]:
    b.append(x)

assert a == b

append可以接受一个可迭代对象作为其参数,但它将其视为单个对象:

a = [1,2]
a.append([3,4])
assert a == [1, 2, [3, 4]]  # not [1, 2, 3, 4]

当你使用 a.extend(str) 时,为什么Python会将字符串视为列表? - Jean
1
它不将其视为列表;它将其视为可迭代对象,即任何可以进行迭代的对象。您可以逐个获取字符串的各个字符来迭代字符串。您可以逐个获取列表或元组的元素来迭代列表或元组。您可以逐个获取字典的键来迭代字典。extend不关心其参数是什么,只要它可以被迭代即可。 - chepner

5
当您运行代码时,您会得到类似于这样的异常:
Traceback (most recent call last):
  File ".../stack.py", line 28, in <module>
    addVectors(v1,v2)
  File ".../stack.py", line 15, in addVectors
    sum_vec.extend( vec1[i] + vec2[i] )
TypeError: 'int' object is not iterable

换句话说,extend方法需要一个可迭代的参数作为输入。而append方法则需要一个项作为输入。
下面是extend和append之间差别的一个小例子:
l = [1, 2, 3, 4]
m = [10, 11]
r = list(m)
m.append(l)
r.extend(l)

print(m)
print(r)

输出:

[10, 11, [1, 2, 3, 4]]
[10, 11, 1, 2, 3, 4]

5
你可以查看关于列表的文档:

list.append会在列表末尾添加一个项目:

将项目追加到列表末尾;相当于 a[len(a):] = [x]。

list.extend使用可迭代对象,并将该对象的所有元素添加到列表末尾:

通过将所有项追加到给定列表来扩展列表;相当于 a[len(a):] = L。

你需要使用:

sum_vec.extend([vec1[i] + vec2[i]]) # note that a list is created

这样可以传递一个只有一个元素的可迭代对象(vec1[i] + vec2[i])。但是当您始终添加单个项时,list.append 更加合适。

2

方法append将其参数作为单个元素添加到列表中,而extend获取一个列表并添加其内容。

letters = ['a', 'b']

letters.extend(['c', 'd'])
print(letters)    # ['a', 'b', 'c', 'd']

letters.append(['e', 'f'])
print(letters)    # ['a', 'b', 'c', 'd', ['e', 'f']]

names = ['Foo', 'Bar']
names.append('Baz')
print(names)   # ['Foo', 'Bar', 'Baz']

names.extend('Moo')
print(names)   # ['Foo', 'Bar', 'Baz', 'M', 'o', 'o']

1

extend需要一个可迭代的参数。如果你想通过单个元素扩展列表,你需要把它放在列表中。

a = []
b = 1

a.extend([b])
a.append(b)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接