Toán tử append () so với + trong danh sách trong Python, tại sao chúng cho kết quả khác nhau?


113

Tại sao hai hoạt động này ( append()tương ứng +) cho kết quả khác nhau?

>>> c = [1, 2, 3]
>>> c
[1, 2, 3]
>>> c += c
>>> c
[1, 2, 3, 1, 2, 3]
>>> c = [1, 2, 3]
>>> c.append(c)
>>> c
[1, 2, 3, [...]]
>>> 

Trong trường hợp cuối cùng thực sự có một đệ quy vô hạn. c[-1]cgiống nhau. Tại sao nó khác với +hoạt động?


1
với tất cả sự tôn trọng đối với một câu hỏi mới khả thi: Tôi đã quay trở lại câu hỏi ban đầu để giữ cho nó sạch sẽ (1 câu hỏi cho mỗi chủ đề, xem SO FAQ). Vui lòng đặt câu hỏi mới hoặc đặt câu hỏi tiếp theo bên trong các chủ đề bình luận bên dưới mỗi câu trả lời. Lưu ý: các chỉnh sửa của bạn không bị mất, hãy nhấp vào lịch sử và bạn có thể sao chép / dán nó vào một câu hỏi mới.
Abel


có vẻ như nó cho các ans khác nhau, nhưng không phải như vậy. Nếu bạn muốn thêm một giá trị bằng cách sử dụng toán tử +, bạn có thể sử dụng dấu []. c + = [c] sẽ cho bạn kết quả tương tự như append.
Sharif Chowdhury,

@SharifChowdhury Tôi tin rằng bạn sẽ nhận được kết quả tương tự
đáng tin cậy vào

Câu trả lời:


142

Để giải thích "tại sao":

Các +hoạt động thêm mảng yếu tố để các mảng ban đầu. Phép array.appendtoán chèn mảng (hoặc bất kỳ đối tượng nào) vào cuối mảng ban đầu, dẫn đến một tham chiếu đến bản thân tại vị trí đó (do đó là đệ quy vô hạn).

Sự khác biệt ở đây là phép toán + hoạt động cụ thể khi bạn thêm một mảng (nó được nạp chồng như những mảng khác, hãy xem chương này về chuỗi) bằng cách nối phần tử. Tuy nhiên, phương thức append thực hiện đúng như những gì bạn yêu cầu: nối đối tượng ở phía bên tay phải mà bạn cung cấp cho nó (mảng hoặc bất kỳ đối tượng nào khác), thay vì lấy các phần tử của nó.

Một sự thay thế

Sử dụng extend()nếu bạn muốn sử dụng một hàm hoạt động tương tự như toán tử + (như các hàm khác cũng được hiển thị ở đây). Thật không khôn ngoan khi làm ngược lại: cố gắng bắt chước chắp thêm với toán tử + cho danh sách (xem liên kết trước đây của tôi về lý do).

Lịch sử nhỏ

Nói cho vui, một chút lịch sử: sự ra đời của mô-đun mảng trong Python vào tháng 2 năm 1993. nó có thể làm bạn ngạc nhiên, nhưng các mảng đã được thêm vào sau khi các chuỗi và danh sách ra đời.


2
+1 vì tôi luôn ủng hộ thông tin chính xác. Liên kết đến tài liệu chính thức luôn là một điểm cộng!
jathanism

10
Một phần khác của "tại sao": những người lành mạnh mong đợi +là đối xứng: nối danh sách với danh sách.
Beni Cherniavsky-Paskin

1
+1, Beni điểm tốt (trong khi tôi có thể coi nó giống như "lành mạnh" khi nói "đối tượng ở phía rh được nối vào mảng ở phía lh", nhưng cá nhân tôi thấy hành vi hiện tại hợp lý hơn).
Abel

nếu một phần tử là chuỗi đơn, ví dụ s = 'word', l = ['this', 'is']. Sau đó, l.append (s) và l + s phải giống nhau. Tôi có đúng không?
user3512680

23

Toán tử nối +là một toán tử infix nhị phân, khi được áp dụng cho danh sách, sẽ trả về một danh sách mới chứa tất cả các phần tử của mỗi trong hai toán hạng của nó. Các list.append()phương pháp là một mutatortrên listđó gắn thêm đơn của objecttham số (trong ví dụ của bạn cụ thể danh sách c) đến chủ đề list. Trong ví dụ của bạn, điều này dẫn đến cviệc thêm một tham chiếu vào chính nó (do đó là đệ quy vô hạn).

Một thay thế cho nối '+'

Các list.extend()phương pháp cũng là một phương pháp mutator mà concatenates nó sequencetranh luận với chủ đề list. Cụ thể, nó nối từng phần tử của sequencetheo thứ tự lặp lại.

An sang một bên

Là một toán tử, +trả về kết quả của biểu thức dưới dạng một giá trị mới. Là một mutatorphương thức không chuỗi , list.extend()sửa đổi danh sách chủ đề tại chỗ và không trả về gì.

Mảng

Tôi đã thêm điều này do sự nhầm lẫn tiềm ẩn mà câu trả lời của Abel ở trên có thể gây ra bằng cách trộn lẫn thảo luận về danh sách, trình tự và mảng. Arraysđã được thêm vào Python sau chuỗi và danh sách, như một cách hiệu quả hơn để lưu trữ các mảng kiểu dữ liệu tích hợp. Đừng nhầm lẫn arraysvới lists. Chúng không giống nhau.

Từ tài liệu mảng :

Mảng là kiểu trình tự và hoạt động rất giống danh sách, ngoại trừ kiểu đối tượng được lưu trữ trong chúng bị hạn chế. Kiểu được chỉ định tại thời điểm tạo đối tượng bằng cách sử dụng mã kiểu, là một ký tự duy nhất.


18

appendđang thêm một phần tử vào danh sách. nếu bạn muốn mở rộng danh sách với danh sách mới mà bạn cần sử dụng extend.

>>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]

4
Tôi đã nghĩ rằng nó khá rõ ràng tại sao kết quả lại khác nhau, bởi vì các hoạt động không giống nhau! nếu nó xuất hiện như vậy +extendtạo ra các kết quả khác nhau mà chúng tôi cần phải suy nghĩ.
SilentGhost

1
+1: Tại sao tôi không thích câu hỏi "tại sao": append+khác. Đó là lý do tại sao. Tôi thích câu trả lời này vì cung cấp những gì làm có ý nghĩa hơn.
S.Lott

Đây không phải là trang web để trả lời các câu hỏi được yêu cầu? Mọi người hỏi tại sao PHP được gọi là PHP và tại sao __lt__không thể nạp chồng trong Python (ngày nay nó có thể). Những câu hỏi tại sao là những câu cần thiết nhất nhưng thường khó trả lời nhất: họ yêu cầu bản chất, không phải cho một con trỏ hướng dẫn. Và tất nhiên: nếu bạn không thích một câu hỏi (tôi không thích nhất), thì đừng trả lời ;-)
Abel

Để chứng minh thêm, có thể hiển thị c += [c]c.append(c[:])quá.
ephemient

2
@Abel: Tại sao a+b != a*bvậy? Chúng là các hoạt động khác nhau. Đó là câu trả lời. "Tại sao" không hữu ích bằng các câu hỏi khác, chẳng hạn như "Làm cách nào để nối thêm đúng cách?" Hoặc "Có gì sai với phần nối này dẫn đến đệ quy vô hạn?" Các câu hỏi dạng "Tôi phải làm gì với X" hoặc "Điều gì đã xảy ra khi tôi thực hiện X"? Hoặc "Tôi nên làm gì thay vì X" cũng sẽ giúp ai đó học hỏi, nhưng sẽ cung cấp các câu trả lời tập trung, có thể sử dụng và hành động được.
S.Lott

8

Danh sách Python là không đồng nhất mà các phần tử trong cùng một danh sách có thể là bất kỳ loại đối tượng nào. Biểu thức: c.append(c)thêm đối tượng cvào danh sách. Trong trường hợp nó tự làm cho danh sách trở thành một thành viên của danh sách.

Biểu thức cộng c += chai danh sách với nhau và gán kết quả cho biến c. +Toán tử nạp chồng được định nghĩa trên danh sách để tạo một danh sách mới có nội dung là các phần tử trong danh sách đầu tiên và các phần tử trong danh sách thứ hai.

Vì vậy, đây thực sự chỉ là những biểu thức khác nhau được sử dụng để làm những việc khác nhau theo thiết kế.


7

Phương pháp bạn đang tìm kiếm là extend(). Từ tài liệu Python :

list.append(x)
    Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend(L)
    Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

list.insert(i, x)
    Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).


2

Xem tài liệu :

list.append (x)

  • Thêm một mục vào cuối danh sách; tương đương với a [len (a):] = [x].

list.extend (L) - Mở rộng danh sách bằng cách thêm tất cả các mục trong danh sách đã cho; tương đương với a [len (a):] = L.

c.append(c)"nối" c với chính nó như một phần tử . Vì danh sách là một kiểu tham chiếu, điều này tạo ra một cấu trúc dữ liệu đệ quy.

c += ctương đương với extend(c), nối các phần tử của c với c.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.