Pythonリストにpop()があるのにpush()がないのはなぜですか


265

最後の要素(-1でインデックスが付けられている)を削除して返すa がすでにあるのに、Pythonのlist.append関数が呼び出さlist.pushれない理由を誰かが知っていますか?list.poplist.appendセマンティクスがその使用と一致している場合ていますか?


21
<nitpick>これはメソッドではなく、関数です。</ nitpick>
Tim Pietzcker

49
これはすばらしい質問だと思いますが、「Pythonリストにpop()があるのにpush()がないのはなぜですか」というフレーズもあるでしょう。
ウリ

6
popリストのどこからでもアイテムをポップできます。 appendリストの真ん中に何かを「プッシュ」することはできません。
内部石2014

@TimPietzcker <nitpick ^ 2>メソッドは確かに関数でもあり、メソッド(メンバー関数)は関数のサブセットです:)
jave.web

回答:


246

「ポップ」が考えられるよりずっと前に「追加」が存在していたからです。Python 0.9.1は、1991年の初めにlist.appendをサポートしました。比較として、1997年にpopを追加することに関するcomp.lang.pythonに関する議論の一部を以下に示します。Guidoは次のように書いています。

スタックを実装するには、list.pop()プリミティブを追加する必要があります(いいえ、原則に基づいてこの特定のものに反対しているわけではありません)。list.push()はlist.pop()との対称性のために追加できますが、同じ操作に複数の名前を付けるのはあまり好きではありません。遅かれ早かれ、もう1つを使用するコードを読むことになるので、両方を学習する必要があります。これはより認知的な負荷です。

また、彼がpush / pop / put / pullが要素[0]にあるのか、要素[-1]の後にあるのか、アイコンのリストへの参照を投稿するのかについて、彼が議論していることも確認できます。

これはすべてリストオブジェクトの実装から除外するのが最善だと思います-特定のセマンティクスでスタックまたはキューが必要な場合は、リストを使用する小さなクラスを記述します

言い換えれば、すでに高速のappend()とdel list [-1]をサポートしているPythonリストとして直接実装されたスタックの場合、list.pop()がデフォルトで最後の要素で機能することは理にかなっています。他の言語では異なる方法で行われる場合でも。

ここで暗黙的なのは、ほとんどの人がリストに追加する必要があるということですが、リストをスタックとして扱う機会が少ないため、list.appendが非常に早くに登場しました。


16
@poige you're going to *read* code that uses the other one (...) which is more cognitive load「プッシュはありません」を覚えていると、コードを記述しているときに認知負荷が発生するだけです。「プッシュは追加の正確な同義語」であることを覚えておくと、使用頻度が低いと思われるものを読むたびに、認知的負荷が発生します。人々が読みやすさがしばしば読みやすさよりも優れていると考える理由の詳細については、stackoverflow.com / questions
3455488 /…を

2
言い訳/意味をなさない
ポジェイ

15

追加するので; 押しません。「追加」はリストの最後に追加し、「プッシュ」は前に追加します。

キューとスタックを考えてください。

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

編集: 2番目の文をより正確に言い換えると、「追加」とは、基礎となる実装に関係なく、リストの最後に何かを追加することを非常に明確に意味します。「プッシュ」されたときに新しい要素が追加される場所は、あまり明確ではありません。スタックにプッシュすることは「トップ」に何かを置くことですが、実際にそれが基礎となるデータ構造のどこに行くかは完全に実装に依存します。一方、キューにプッシュすることは、キューを最後に追加することを意味します。


4
チュートリアルは、最後から単にプッシュおよびポップすることを示唆しているようです:「リストメソッドを使用すると、リストをスタックとして非常に簡単に使用できます。追加された最後の要素は、最初に取得された要素です(「後入れ先出し」 ”)。スタックの一番上にアイテムを追加するには、append()を使用します。スタックの一番上からアイテムを取得するには、明示的なインデックスなしでpop()を使用します。 "
Uri

110
「押す」とは、決して前に追加することを意味しません。正気な人がスタックの一番下(開始)ではなく、一番上(終了)に「プッシュ」したスタックのすべての実装
Kip

4
修正:すべての*配列ベースの実装。リンクリストの実装は頭にプッシュされます。
キップ

16
JavaScript pushが最後に追加されます。
コビ、

2
いいえ、list.popセマンティクスを考慮に入れて、list.append要素をスタックとして表示すると、リストに要素がプッシュされます。
Fortran、2009年

10

リストに要素を追加するためですか?プッシュは通常、スタックを参照するときに使用されます。


7
リストはスタックにすることもできます。:-)
Jason Baker、

@JasonBakerリストを使用してスタックを実装できますが、これはlist == stackを意味するものではありません。本当に必要であれば、キューを使用してスタックを実装することもできます。(それはひどく非効率的ですが、それは可能です!)
Mark E. Haase

混乱は、スタックにリストのような「開始」または「終了」がなく、むしろ「トップ」と「ボトム」があるという事実から実際に生じます。スタックに追加することは、要素を上に配置して「押し下げる」ことを意味します。フロントで「押す」ことは意味がありません(少なくとも言語的には)。さらに、混乱を招くために、C ++では「push_front」と「push_back」を使用しています。
JesperE 2013

9

「追加」は直感的に「リストの最後に追加」を意味するためです。「プッシュ」と呼ばれる場合、リストの末尾に追加するのか、リストの先頭に追加するのかは不明です。


12
pop操作があるので、これは意味がありません。以来pushpop通常の操作をスタックし、一緒に行くされている、彼らが、リストの同じ端に作動することが期待されなければなりません。
jamesdlin 2013

7

公式な回答ではありませんが(言語の使用に基づく推測にすぎません)、Pythonではリストをスタックとして使用できます(たとえば、チュートリアルのセクション5.1.1)。ただし、リストは依然として最初にリストであるため、両方に共通する操作では、スタック用語(つまり、プッシュ)ではなくリスト用語(つまり、追加)を使用します。リストではpop操作はそれほど一般的ではないため( 'removeLast'を使用することもできます)、pop()を定義しましたが、push()は定義しませんでした。


3

OK、ここの個人的な意見ですが、AppendとPrependはセット内の正確な位置を意味します。

PushとPopは、セットのどちらかの端に適用できる実際の概念です...一貫している限り...何らかの理由で、私には、Push()は、セットする...


3
育てたので、配列に.append()関数がある場合、対応する.prepend()関数がないのはなぜですか?先頭に.insert(0、val)を使用する方法を学ぶことができますが、対応する.delete(pos、val)関数がないことに困惑しています。ref:docs.python.org/2/library/array.html
MarkHu

3

参考までに、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]

スタックはやや抽象的なデータ型です。「プッシュ」と「ポップ」の考え方は、スタックが実際にどのように実装されているかに大きく依存しません。たとえば、理論的には次のようなスタックを実装できます(なぜそうするのかはわかりませんが)。

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

...そしてリンクリストを使用してスタックを実装することに慣れていません。


1

プッシュは定義されたスタック動作です。Aをスタック(B、C、D)にプッシュすると、(A、B、C、D)になります。

Python追加を使用した場合、結果のデータセットは(B、C、D、A)のようになります。

編集:うわー、聖なる歩兵。

私の例から、リストのどの部分が一番上で、どの部分が一番下かは明らかだと思います。ここで私たちのほとんどが左から右に読んでいると仮定すると、リストの最初の要素は常に左側になります。


1
そうではありません。popはリストの最後からではなく、最後から削除します。
Fortran、2009年

4
リンク先のページを読んでください。プッシュは、スタックの一番上にプッシュすることと定義されています。どちらが「トップ」かは実装に依存します。配列ベースのスタックでは、pushは配列の最後にプッシュします。リンクリストベースのスタックでは、pushは最初にプッシュします。
キップ

0

Pythonのオリジナルバージョン(C Python)がC ++ではなくCで記述されたためと考えられます。

リストを何かの後ろに押し込むことによってリストが形成されるという考えは、それらを追加するという考えほどよく知られていません。


2番目の部分は良い答えです。しかし、それはC / C ++での実装とどう関係しているのでしょうか。
Jason Baker、

@ジェイソン:C ++のSTLでは、push_back()はリストに追加する方法です。C ++で作業している場合は、リストがプッシュによって形成されるという考えがおそらくポップアップする可能性が高いというメタアイデアを伝えようとしていました。わかりましたか?
アンワインド

リスト型を連続した配列(C ++のベクトル、Pythonのリスト、Perlの配列)として実装している場合は、新しい要素を「プッシュ」で最後に配置するのが理にかなっています。perl 4は、Pythonのappend / popやC ++のpush_back / pop_backとまったく同じように、またSTLがC ++に正式に提案されるずっと前に、配列の関数として「push」と「pop」を想定していたことに注意してください。したがって、C ++のSTLが物事の新しい理解を生み出すこととは関係ありません。
Andrew Dalke、

PerlのバックグラウンドからPythonを習得できない点の1つは、組み込みのpush()、pop()、shift()、およびunshift()操作を使用して、同じ要素の両端に要素を追加/削除する機能です。配列。Pythonリストを「Stackish」クラスまたは「Queueish」クラスに簡単にラップすることはできますが、両方を一度に行うのはそれほど簡単(または効率的)ではありません。
Peter

-2

プッシュアンドポップは、カフェテリアまたはビュッフェのプレートまたはトレイのスタックのメタファーの観点から理解できます。具体的には、トッププレートが(多かれ少なかれ...理論的には)下にスプリングがあるタイプのホルダーです。その下にいくつのプレートがあっても同じ場所に。

トレイを取り外すと、スプリングの重さが少し減り、スタックが少し「飛び出し」ます。プレートを元に戻すと、スタックが「押し下げ」られます。したがって、リストをスタックとして、最後の要素を上にあると考える場合、それほど混乱することはないはずです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.