2009-10-14 2 views
222

Кто-нибудь знает, почему функция list.append Python не называется list.push, так как уже есть list.pop, который удаляет и возвращает последний элемент (который индексируется в -1) и list.append семантический согласуется с этим использованием?Почему Python «добавляет» не «push»?

+20

Это метод, а не функция.

+46

Я думаю, что это отличный вопрос, хотя его, возможно, следует сформулировать следующим образом: «Почему списки python имеют pop(), но не push()». – Uri

+5

'pop' может вытаскивать предметы из любого места в списке. 'append' не может« толкать »что-то в середину списка. – endolith

ответ

212

Потому что «append» существовал задолго до того, как «поп» считался. Python 0.9.1 поддерживается list.append в начале 1991 года сравнения, вот часть discussion on comp.lang.python о добавлении поп в 1997 году Гвидо писал:

Чтобы реализовать стек, можно было бы необходимо добавить list.pop() примитив (и нет, я не против этого один на основе любого принципа). list.push() может быть добавлен для симметрии с list.pop(), но я не большой поклонник нескольких имен для той же операции - рано или поздно вы собираетесь прочитать код, который использует другой, так что вам нужно узнать , что является более познавательной нагрузкой.

Вы также можете видеть, что он обсуждает идею, если нажать/поп/ставить/тянуть должен быть элемент [0] или после элемента [-1], где он отправляет ссылку на список иконы в:

я стил думаю, что все это лучше всего оставил из объекта списка реализации - если вам нужен стек, или очередь, с определенными семантики, написать небольшой класс, который использует списки

Другими словами, для стеков, реализованных непосредственно в виде списков Python, которые уже поддерживают быстрый список append() и del [-1], имеет смысл, что list.pop() работает по умолчанию для последнего элемента. Даже если другие языки делают это по-другому.

Неясно, что большинство людей нужно добавить в список, но у многих меньше есть возможность рассматривать списки как стеки, поэтому list.append пришел намного раньше.

+15

Мне нравится эта часть о «когнитивной нагрузке». Итак, теперь вы должны помнить, что есть append(), и нет push(). Никакой нагрузки, да? – poige

+4

@poige 'вы собираетесь * читать * код, который использует другой (...), который является более познавательной загрузкой. Помните, что« нет толчка »вводит когнитивную нагрузку только при написании кода. Помните, что «push - это точный синоним для добавления» вводит когнитивную нагрузку, когда вы читаете ту, которую вы видите, используемой реже. См. Http://stackoverflow.com/questions/3455488/code-is-read-more-than-it-is-written для получения дополнительной информации о том, почему люди думают, что читаемость часто превосходит возможности записи. – stevenjackson121

+0

Не делает извинения/смысла – poige

12

Потому что он добавляет; он не толкает. «Добавление» добавляет к концу списка, «pushing» добавляет к фронту.

Подумайте о очереди против стека.

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

Edit: Изложить мое второе предложение более точно, «Прикрепление» очень ясно подразумевает, что-то добавить к концу списка, независимо от конкретной реализации. Когда новый элемент добавляется, когда он «толкается», становится менее ясным. Нажатие на стеке ставит что-то «сверху», но там, где он действительно находится в базовой структуре данных, полностью зависит от реализации. С другой стороны, нажатие на очередь подразумевает добавление ее в конец.

+4

Учебное пособие, по-видимому, предполагает, что он просто толкает и выскакивает с конца: «Методы списка упрощают использование списка в виде стека, где последний добавленный элемент - это первый извлеченный элемент (« last-in, first- in, out "). Чтобы добавить элемент в начало стека, используйте append(). Чтобы извлечь элемент из верхней части стека, используйте pop() без явного индекса." – Uri

+92

"pushing" никоим образом не означает добавление спереди. каждая реализация стека, которая когда-либо была написана разумным человеком, «толкает» на верхнюю часть (конец) стека, а не на нижнюю (начальную) стека – Kip

+4

* исправление: каждая * реализация на основе массива *. реализация связанного списка будет подталкиваться к голове. – Kip

10

Потому что он добавляет элемент в список? Push обычно используется при обращении к стекам.

+6

Список может быть стеком. :-) –

+0

@JasonBaker Вы можете реализовать стек, используя список, но это не означает, что list == stack. Вы также можете реализовать стек, используя очередь, если хотите. (Это было бы ужасно неэффективно, но это возможно!) –

+0

Путаница действительно исходит из того факта, что стек не имеет «начало» или «конец», как список, а скорее «верхний» и «нижний», , Добавление в стек предполагает размещение элемента сверху и «нажатие» вниз. «Pushing» на фронте не имеет смысла (по крайней мере, не лингвистически). И для того, чтобы сделать вещи еще более запутанными, C++ использует «push_front» и «push_back». – JesperE

0

Возможно, потому что исходная версия Python (C Python) была написана на C, а не на C++.

Идея о том, что список формируется путем нажатия вещей на спину чего-то, вероятно, не так хорошо известен, как мысль о добавлении их.

+0

Вторая часть - хороший ответ. Но что это связано с реализацией в C/C++? –

+0

@Jason: В STL на C++ push_back() - это то, как вы добавляете к списку. Я пытался передать мета-идею, что идея, что списки формируются путем нажатия, возможно, более вероятно, появится, если вы работаете на C++. Иметь смысл? – unwind

+0

Если у вас есть тип списка, реализованный как непрерывный массив (вектор в C++, список в Python, массив в Perl), тогда имеет смысл «push» положить новый элемент в конец. Обратите внимание, что perl 4 предполагал «push» и «pop» как функции на массивах точно так же, как append/pop Python и push_back/pop_back C++, и задолго до того, как STL было официально предложено C++. Поэтому он не имеет ничего общего с STL C++, создающим новое понимание вещей. –

9

Потому что «append» интуитивно означает «добавить в конце списка». Если бы это называлось «толчок», тогда было бы непонятно, добавляем ли мы материал в хвост или во главе списка.

+8

Это не имеет смысла, так как есть операция 'pop'. Поскольку 'push' и' pop' обычно являются операциями стека и идут вместе, следует ожидать, что они будут работать в одном и том же конце списка. – jamesdlin

-1

Push - это определенное поведение stack; если вы нажмете A на стек (B, C, D), вы получите (A, B, C, D).

Если вы использовали питона Append, полученный набор данных будет выглядеть (B, C, D, A)

Edit: Wow, святой педантизма.

Я бы предположил, что из моего примера будет ясно, какая часть списка - верхняя, а какая часть - нижняя. Предполагая, что большинство из нас здесь читается слева направо, первый элемент любого списка всегда будет слева.

+0

Это неправда, pop удаляется с конца списка, а не спереди. – fortran

+4

читайте страницу, на которую вы ссылаетесь. push определяется как нажатие на верхнюю часть стека. конец которого является «вершиной», зависит от реализации. в стеке на основе массива push нажимал бы на конец массива. в стеке с привязанным списком push будет продвигаться к началу. – Kip

+2

Вы получаете упрек от меня, чтобы компенсировать ненужные downvotes. – AndyPerfect

7

Не является официальным ответом любым способом (просто предположение, основанное на использовании языка), но Python позволяет использовать списки в виде стеков (например, section 5.1.1 of the tutorial). Тем не менее, список по-прежнему является прежде всего списком, поэтому операции, которые являются общими для обоих, используют термины списка (то есть append), а не термины стека (т. Е. Push). Поскольку поп-операция не так распространена в списках (хотя «removeLast» мог быть использован), они определили pop(), но не push().

3

Хорошо, личное мнение здесь, но Append и Prepend подразумевают точное положение в наборе.

Push and Pop - это действительно концепции, которые могут быть применены к любому концу набора ... До тех пор, пока вы согласны ... По какой-то причине для меня Push() кажется, что он должен применяться к перед комплектом ...

+3

Так как вы его подняли, если у массивов есть функция .append(), то почему нет соответствующей функции .prepend()? Я могу научиться использовать .insert (0, val) для добавления, но затем смущен отсутствием соответствующей функции .delete (pos, val). ref: http://docs.python.org/2/library/array.html – MarkHu

3

FYI, это не очень сложно сделать список, который имеет метод нажимной:

>>> 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] 

Стек представляет собой несколько абстрактный тип данных. Идея «pushing» и «popping» в значительной степени не зависит от того, как стек фактически реализован. Например, вы могли бы теоретически реализовать стек, как это (хотя я не знаю, почему вы бы):

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

... и я не получил в использовании связанных списков для реализации стека.

-1

Push и Pop имеют смысл с точки зрения метафоры стопки тарелок или подносов в столовой или буфете, в частности, в типе держателя, который имеет под ним пружину, поэтому верхняя пластина (более или менее). теоретически) в том же месте, независимо от того, сколько пластин находится под ним.

Если вы удалите лоток, вес на пружине будет немного меньше, а стопка «немного выскочит», если вы положите пластину обратно, она «надавит» на стопку вниз. Поэтому, если вы считаете, что список как стек, а последний элемент - сверху, то вам не должно быть путаницы.

Смежные вопросы