Sự khác biệt giữa:
some_list1 = []
some_list1.append("something")
và
some_list2 = []
some_list2 += ["something"]
Sự khác biệt giữa:
some_list1 = []
some_list1.append("something")
và
some_list2 = []
some_list2 += ["something"]
Câu trả lời:
Đối với trường hợp của bạn, điểm khác biệt duy nhất là hiệu suất: append nhanh hơn gấp đôi.
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
Trong trường hợp chung, append
sẽ thêm một mục vào danh sách, trong khi +=
sẽ sao chép tất cả các phần tử của danh sách bên phải vào danh sách bên trái.
Cập nhật: phân tích hiệu suất
So sánh các mã byte, chúng ta có thể giả định rằng append
phiên bản lãng phí chu kỳ trong LOAD_ATTR
+ CALL_FUNCTION
và + = phiên bản - in BUILD_LIST
. Rõ ràng là BUILD_LIST
vượt trội hơn 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
Chúng tôi có thể cải thiện hiệu suất nhiều hơn nữa bằng cách loại bỏ LOAD_ATTR
chi phí:
>>> timeit.Timer('a("something")', 's = []; a = s.append').timeit()
0.15924410999923566
append
vs +=
, thì bạn phải bao gồm việc tạo danh sách như một phần của phép đo. Nếu không, nó sẽ là một câu hỏi khác ( extend
vs +=
).
Trong ví dụ bạn đã đưa ra, không có sự khác biệt, về đầu ra, giữa append
và +=
. Nhưng có một sự khác biệt giữa append
và +
(mà câu hỏi ban đầu được hỏi về).
>>> 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
Như bạn thấy, append
và +=
có cùng một kết quả; họ thêm mục đó vào danh sách mà không tạo danh sách mới. Việc sử dụng +
sẽ thêm hai danh sách và tạo ra một danh sách mới.
append
thêm một mục vào danh sách, trong khi + = thêm nhiều như có trong danh sách khác (tức là bí danh cho extend
). Nhưng anh ấy / cô ấy biết điều đó rồi, đánh giá theo cách viết câu hỏi. Có một số khác biệt khác mà tôi đang thiếu?
+ = là một phép gán. Khi bạn sử dụng nó, bạn thực sự đang nói 'some_list2 = some_list2 + [' something ']'. Nhiệm vụ liên quan đến việc đóng lại, vì vậy:
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
Toán tử + = cũng thường tạo một đối tượng danh sách mới như list + list thường làm:
>>> l1= []
>>> l2= l1
>>> l1.append('x')
>>> l1 is l2
True
>>> l1= l1+['x']
>>> l1 is l2
False
Tuy nhiên trên thực tế:
>>> l2= l1
>>> l1+= ['x']
>>> l1 is l2
True
Điều này là do các danh sách Python triển khai __iadd __ () để tạo ngắn mạch + = tăng cường gán và gọi list.extend () thay thế. (Nó hơi kỳ lạ ở điều này: nó thường làm theo ý bạn, nhưng vì những lý do khó hiểu.)
Nói chung, nếu bạn đang thêm / mở rộng một danh sách hiện có và bạn muốn giữ tham chiếu đến cùng một danh sách (thay vì tạo một danh sách mới), tốt nhất nên rõ ràng và gắn bó với append () / expand () các phương pháp.
some_list2 += ["something"]
thực sự là
some_list2.extend(["something"])
cho một giá trị, không có sự khác biệt. Tài liệu nói rằng:
s.append(x)
giốngs[len(s):len(s)] = [x]
s.extend(x)
nhưs[len(s):len(s)] = x
Vì vậy, rõ ràng s.append(x)
là giống nhưs.extend([x])
Sự khác biệt là nối sẽ làm phẳng danh sách kết quả, trong khi nối thêm sẽ giữ nguyên các cấp:
Vì vậy, ví dụ với:
myList = [ ]
listA = [1,2,3]
listB = ["a","b","c"]
Sử dụng append, bạn sẽ có một danh sách các danh sách:
>> myList.append(listA)
>> myList.append(listB)
>> myList
[[1,2,3],['a',b','c']]
Thay vào đó, sử dụng nối, bạn sẽ có một danh sách phẳng:
>> myList += listA + listB
>> myList
[1,2,3,"a","b","c"]
Các bài kiểm tra hiệu suất ở đây không đúng:
ví dụ
timeit.Timer ('for i in xrange (100): app (i)', 's = []; app = s.append'). timeit ()
các bài kiểm tra hay có thể tham khảo tại đây: http://markandclick.com/1/post/2012/01/python-list-append-vs.html
+= [one_var]
. Nếu chúng ta bỏ qua việc tạo danh sách, + = sẽ trở thành tùy chọn nhanh nhất.
Ngoài các khía cạnh được mô tả trong các câu trả lời khác, append và + [] có các hành vi rất khác nhau khi bạn đang cố gắng tạo một danh sách các danh sách.
>>> list1=[[1,2],[3,4]]
>>> list2=[5,6]
>>> list3=list1+list2
>>> list3
[[1, 2], [3, 4], 5, 6]
>>> list1.append(list2)
>>> list1
[[1, 2], [3, 4], [5, 6]]
list1 + ['5', '6'] thêm '5' và '6' vào list1 dưới dạng các phần tử riêng lẻ. list1.append (['5', '6']) thêm danh sách ['5', '6'] vào list1 dưới dạng một phần tử duy nhất.
Hành vi liên kết được đề cập trong các câu trả lời khác thực sự quan trọng trong một số trường hợp nhất định:
>>> a = ([],[])
>>> a[0].append(1)
>>> a
([1], [])
>>> a[1] += [1]
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Đó là bởi vì phép gán tăng cường luôn liên kết lại, ngay cả khi đối tượng được thay đổi tại chỗ. Sự ràng buộc ở đây xảy ra a[1] = *mutated list*
, không hoạt động đối với các bộ giá trị.
hãy lấy một ví dụ trước
list1=[1,2,3,4]
list2=list1 (that means they points to same object)
if we do
list1=list1+[5] it will create a new object of list
print(list1) output [1,2,3,4,5]
print(list2) output [1,2,3,4]
but if we append then
list1.append(5) no new object of list created
print(list1) output [1,2,3,4,5]
print(list2) output [1,2,3,4,5]
extend(list) also do the same work as append it just append a list instead of a
single variable
Phương thức append () thêm một mục vào danh sách hiện có
some_list1 = []
some_list1.append("something")
Vì vậy, ở đây some_list1 sẽ được sửa đổi.
Đã cập nhật:
Trong khi việc sử dụng + để kết hợp các phần tử của danh sách (nhiều hơn một phần tử) trong danh sách hiện có tương tự như phần mở rộng (được sửa bởi Flux ).
some_list2 = []
some_list2 += ["something"]
Vì vậy, ở đây some_list2 và ["something"] là hai danh sách được kết hợp.
+=
không trả về một danh sách mới. Câu hỏi thường gặp về lập trình cho biết: "... đối với danh sách, __iadd__
tương đương với việc gọi extend
vào danh sách và trả về danh sách. Đó là lý do tại sao chúng tôi nói rằng đối với danh sách, +=
là" viết tắt "cho list.extend
". Bạn cũng có thể tự mình thấy điều này trong mã nguồn CPython: github.com/python/cpython/blob/v3.8.2/Objects/…
extend
.