2009-10-14 31 views
222

Có ai biết tại sao hàm list.append của Python không được gọi là list.push cho rằng đã có list.pop để loại bỏ và trả về phần tử cuối cùng (được lập chỉ mục tại -1) và ngữ nghĩa list.append nhất quán với việc sử dụng đó?Tại sao Python "chắp thêm" không "đẩy"?

+20

Đó là một phương pháp chứ không phải chức năng.

+46

Tôi nghĩ rằng đây là một câu hỏi hay, mặc dù nó có lẽ nên được diễn đạt: "Tại sao các danh sách python có pop() nhưng không đẩy()". – Uri

+5

'pop' có thể bật các mục ra khỏi bất kỳ đâu trong danh sách. 'append' không thể" đẩy "cái gì đó vào giữa danh sách. – endolith

Trả lời

212

Vì "nối thêm" tồn tại lâu trước khi "pop" được nghĩ tới. Python 0.9.1 hỗ trợ list.append vào đầu năm 1991. Để so sánh, đây là một phần của một discussion on comp.lang.python về việc thêm pop vào năm 1997. Guido đã viết:

Để thực hiện một chồng, người ta sẽ cần để thêm một list.pop() nguyên thủy (và không, tôi không chống lại điều này cụ thể một trên cơ sở của bất kỳ nguyên tắc). list.push() có thể được thêm cho đối số đối xứng với list.pop() nhưng tôi không phải là một người hâm mộ lớn gồm nhiều tên cho hoạt động tương tự - sớm hay muộn bạn sẽ đọc mã sử dụng một cái khác, vì vậy bạn cần phải tìm hiểu cả hai, đó là tải nhận thức nhiều hơn.

Bạn cũng có thể thấy ông thảo luận về ý tưởng nếu push/pop/đặt/pull nên có ít yếu tố [0] hoặc sau element [-1] nơi ông đăng tải một tài liệu tham khảo vào danh sách Biểu tượng của:

tôi stil nghĩ rằng tất cả điều này là tốt nhất gạt ra khỏi danh sách các đối tượng thực hiện - nếu bạn cần một chồng, hoặc một hàng đợi, trong đó đặc biệt ngữ nghĩa, hãy viết một lớp học nhỏ mà sử dụng một danh sách

Nói cách khác, đối với các ngăn xếp được triển khai trực tiếp dưới dạng danh sách Python, đã hỗ trợ nối thêm nhanh() và danh sách del [-1], có nghĩa là list.pop() hoạt động theo mặc định trên phần tử cuối cùng. Ngay cả khi các ngôn ngữ khác làm điều đó khác đi.

Ngụ ý ở đây là hầu hết mọi người cần phải nối thêm vào danh sách, nhưng nhiều người ít có dịp xem các danh sách dưới dạng ngăn xếp, đó là lý do tại sao list.append đến sớm hơn rất nhiều.

+15

Tôi thích phần này về "tải nhận thức". Vì vậy, bây giờ bạn phải nhớ rằng có append(), và không có push(). Không tải gì cả, đúng không? – poige

+4

@poige 'bạn sẽ * đọc * mã sử dụng mã khác (...) là tải nhận thức nhiều hơn. Nhớ rằng" không có push "chỉ giới thiệu tải nhận thức khi bạn viết mã. Ghi nhớ "push là một từ đồng nghĩa chính xác cho nối thêm" giới thiệu tải nhận thức bất cứ khi nào bạn đọc một trong những bạn thấy sử dụng ít thường xuyên hơn. Xem http://stackoverflow.com/questions/3455488/code-is-read-more-than-it-is-written để biết thêm về lý do khiến mọi người nghĩ rằng khả năng đọc thường vượt quá khả năng ghi – stevenjackson121

+0

Làm cho không có lý do/ý nghĩa nào – poige

12

Vì nó gắn thêm; nó không đẩy. "Thêm" thêm vào cuối danh sách, "đẩy" thêm vào phía trước.

Nghĩ về hàng đợi so với chồng.

http://docs.python.org/tutorial/datastructures.html

Edit: Để xây dựng lại và câu thứ hai của tôi chính xác hơn, "Phụ thêm" rất rõ ràng ngụ ý thêm cái gì đó để các cuối của một danh sách, không phụ thuộc vào thực hiện cơ bản. Khi một phần tử mới được thêm vào khi nó được "đẩy" thì không rõ ràng. Đẩy vào một ngăn xếp là đặt một cái gì đó vào "đầu", nhưng nơi nó thực sự đi trong cấu trúc dữ liệu cơ bản hoàn toàn phụ thuộc vào việc thực hiện. Mặt khác, đẩy vào một hàng đợi ngụ ý thêm nó vào cuối.

+4

Hướng dẫn dường như gợi ý rằng nó đơn giản đẩy và bật từ cuối: "Các phương thức danh sách làm cho nó rất dễ sử dụng một danh sách như một ngăn xếp, trong đó phần tử cuối được thêm vào là phần tử đầu tiên được lấy ra (" last-in, first- Để thêm một mục vào đầu ngăn xếp, hãy dùng append() Để lấy một mục từ trên cùng của ngăn xếp, sử dụng pop() mà không có chỉ mục rõ ràng. " – Uri

+92

" đẩy "theo cách không có nghĩa là thêm phía trước. mọi việc thực hiện của một ngăn xếp đã từng được viết bởi một người lành mạnh "đẩy" lên đầu (cuối) của ngăn xếp, chứ không phải dưới cùng (bắt đầu) của ngăn xếp – Kip

+4

* hiệu chỉnh: mọi triển khai * dựa trên mảng *. thực hiện danh sách liên kết sẽ đẩy lên đầu. – Kip

10

Vì nó gắn thêm một phần tử vào danh sách? Đẩy thường được sử dụng khi đề cập đến ngăn xếp.

+6

Một danh sách có thể là một ngăn xếp mặc dù. :-) –

+0

@JasonBaker Bạn có thể thực hiện một ngăn xếp bằng cách sử dụng một danh sách, nhưng điều đó không có nghĩa là danh sách == ngăn xếp. Bạn cũng có thể thực hiện một ngăn xếp bằng cách sử dụng một hàng đợi, nếu bạn thực sự muốn. (Nó sẽ là khủng khiếp không hiệu quả, nhưng nó có thể!) –

+0

Sự nhầm lẫn thực sự xuất phát từ thực tế là một ngăn xếp không có một "bắt đầu" hoặc "kết thúc" như một danh sách, mà là một "đầu" và "đáy" . Việc thêm vào ngăn xếp ngụ ý đặt một phần tử lên trên và "đẩy" xuống. "Đẩy" ở phía trước làm cho không có ý nghĩa (ít nhất là không ngôn ngữ). Và chỉ để làm cho mọi việc trở nên khó hiểu hơn, C++ sử dụng "push_front" và "push_back". – JesperE

0

Có thể vì phiên bản gốc của Python (C Python) được viết bằng C, chứ không phải C++.

Ý tưởng rằng danh sách được hình thành bằng cách đẩy mọi thứ vào mặt sau của một thứ có lẽ không nổi tiếng như ý nghĩ phụ thêm chúng.

+0

Phần thứ hai là câu trả lời hay. Nhưng điều đó có liên quan gì đến việc được triển khai trong C/C++? –

+0

@ Jason: Trong STL của C++, push_back() là cách bạn thêm vào danh sách. Tôi đã cố gắng truyền đạt ý tưởng meta rằng ý tưởng rằng các danh sách được hình thành bằng cách đẩy có lẽ nhiều khả năng bật lên nếu bạn đang làm việc trong C++. Có ý nghĩa gì không? – unwind

+0

Nếu bạn có một kiểu danh sách được thực hiện như một mảng liền kề (một vecto trong C++, một danh sách trong Python, một mảng trong Perl) thì có nghĩa là "đẩy" đặt phần tử mới ở cuối. Bạn sẽ lưu ý rằng perl 4 được cho là "push" và "pop" như các hàm trên các mảng giống như append/pop của Python và push_back/pop_back của C++, và trước khi STL được chính thức đề xuất với C++. Vì vậy, nó không có gì để làm với C + + của STL tạo ra một sự hiểu biết mới về sự vật. –

9

Vì "chắp thêm" có nghĩa là "thêm ở cuối danh sách". Nếu nó được gọi là "đẩy", thì nó sẽ không rõ ràng cho dù chúng ta đang thêm công cụ ở đuôi hay ở đầu danh sách.

+8

Điều này không có ý nghĩa vì có một hoạt động 'pop'. Vì 'push' và' pop' thường là các hoạt động chồng và đi cùng nhau, nên chúng được mong đợi rằng chúng hoạt động trên cùng một đầu của danh sách. – jamesdlin

-1

Đẩy là hành vi được xác định stack; nếu bạn đẩy A vào ngăn xếp (B, C, D) bạn sẽ nhận được (A, B, C, D).

Nếu bạn sử dụng python append, bộ dữ liệu kết quả sẽ như thế nào (B, C, D, A)

Edit: Wow, thầy giáo thánh.

Tôi cho rằng nó sẽ rõ ràng từ ví dụ của tôi mà một phần của danh sách là phần trên cùng và phần nào là phần dưới cùng. Giả sử rằng hầu hết chúng ta ở đây đọc từ trái sang phải, yếu tố đầu tiên của bất kỳ danh sách nào luôn ở bên trái.

+0

Điều đó không đúng, pop sẽ xóa khỏi danh sách kết thúc, không phải từ phía trước. – fortran

+4

đọc trang bạn liên kết đến. đẩy được định nghĩa là đẩy lên trên cùng của ngăn xếp. mà kết thúc là "đầu" phụ thuộc vào việc thực hiện. trong một ngăn xếp dựa trên mảng, push sẽ đẩy lên cuối mảng. trong ngăn xếp dựa trên danh sách được liên kết, việc đẩy sẽ đẩy tới đầu. – Kip

+2

Bạn nhận được một upvote từ tôi để bù đắp các downvotes không cần thiết. – AndyPerfect

7

Không phải là câu trả lời chính thức bằng bất kỳ phương tiện nào (chỉ là phỏng đoán dựa trên việc sử dụng ngôn ngữ), nhưng Python cho phép bạn sử dụng danh sách làm ngăn xếp (ví dụ: section 5.1.1 of the tutorial). Tuy nhiên, danh sách vẫn là danh sách đầu tiên, do đó các hoạt động phổ biến cho cả hai thuật ngữ sử dụng danh sách (ví dụ: nối thêm) thay vì các thuật ngữ ngăn xếp (tức là, đẩy). Kể từ khi một hoạt động pop không phải là phổ biến trong danh sách (mặc dù 'removeLast' có thể đã được sử dụng), họ đã xác định một pop() nhưng không phải là một push().

3

Ok, ý kiến ​​cá nhân ở đây, nhưng Nối và Đăng ký ngụ ý các vị trí chính xác trong một tập hợp.

Push and Pop thực sự là khái niệm có thể được áp dụng cho cả hai đầu của một tập ... Chỉ cần miễn là bạn nhất quán ... Vì lý do nào đó, với tôi, Push() có vẻ như nó sẽ áp dụng cho mặt trước của một bộ ...

+3

Vì bạn đã đưa nó lên, nếu mảng có hàm .append(), thì tại sao không có hàm tương ứng.prepend()? Tôi có thể học cách sử dụng .insert (0, val) để thêm vào, nhưng sau đó lại xấu hổ vì thiếu một hàm .delete (pos, val) tương ứng. ref: http://docs.python.org/2/library/array.html – MarkHu

3

FYI, nó không phải là quá khó khăn để tạo ra một danh sách đó có một phương thức push:

>>> class StackList(list): 
...  def push(self, item): 
...    self.append(item) 
... 
>>> x = StackList([1,2,3]) 
>>> x 
[1, 2, 3] 
>>> x.push(4) 
>>> x 
[1, 2, 3, 4] 

Một stack là một datatype hơi trừu tượng. Ý tưởng "đẩy" và "popping" phần lớn độc lập với cách chồng thực sự được triển khai. Ví dụ: về mặt lý thuyết bạn có thể triển khai một ngăn xếp như thế này (mặc dù tôi không biết tại sao bạn lại muốn):

l = [1,2,3] 
l.insert(0, 1) 
l.pop(0) 

... và tôi chưa sử dụng danh sách được liên kết để triển khai chồng.

-1

Push and Pop có ý nghĩa về phép ẩn dụ của một chồng đĩa hoặc khay trong quán ăn tự chọn, đặc biệt là loại trong ngăn chứa có lò xo bên dưới sao cho tấm trên cùng (nhiều hoặc ít hơn). trong lý thuyết) ở cùng một vị trí bất kể có bao nhiêu đĩa nằm dưới nó.

Nếu bạn tháo khay, trọng lượng trên lò xo sẽ ​​ít hơn một chút và ngăn xếp "bật" lên một chút, nếu bạn đặt tấm lại, nó sẽ "đẩy" ngăn xếp xuống. Vì vậy, nếu bạn nghĩ về danh sách như là một ngăn xếp và các yếu tố cuối cùng như đang được trên đầu trang, sau đó bạn không nên có nhiều nhầm lẫn.

Các vấn đề liên quan