파이썬 목록에 pop ()이 있지만 push ()가없는 이유


265

이미 -1에서 색인 된 마지막 요소를 제거하고 반환하고 의미가 해당 용도와 일치하는 파이썬 list.append함수가 호출되지 않은 이유를 아는 사람이 있습니까?list.pushlist.poplist.append


21
<nitpick> 함수가 아닌 방법입니다. </ nitpick>
Tim Pietzcker

49
"파이썬 목록에 pop ()은 있지만 push ()는없는 이유는 무엇입니까?"
Uri

6
pop목록의 어느 곳에서나 항목을 표시 할 수 있습니다. append목록 중간에 무언가를 "밀어 넣을"수 없습니다.
endolith

@TimPietzcker <nitpick ^ 2> 메소드는 실제로 함수이며 메소드 (멤버 함수)는 함수의 서브 세트입니다. :)
jave.web

답변:


246

"추가"는 "팝"이 생각되기 오래 전에 존재했기 때문에. 파이썬 0.9.1 은 1991 년 초에 list.append를 지원했습니다. 이에 비해 1997 년에 pop을 추가 하는 것에 대한 comp.lang.python 에 대한 토론 의 일부가 있습니다 . Guido는 다음과 같이 썼습니다.

스택을 구현하려면 list.pop () 프리미티브를 추가해야합니다 (그리고 원칙에 따라이 특정 스택에 반대하지 않습니다). list.pop ()을 사용하여 대칭을 위해 list.push ()를 추가 할 수는 있지만 동일한 작업에 대해 여러 이름을 많이 사용하지는 않습니다. 조만간 다른 코드를 사용하는 코드를 읽을 것이므로 인지력이 높은 두 가지를 모두 배워야합니다.

또한 그는 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/… 를 참조하십시오
stevenjackson121

2
변명의 여지가 없습니다
poige

15

그것이 추가되기 때문에; 밀지 않습니다. "추가"는 목록의 끝에 추가하고 "푸시"는 앞에 추가합니다.

대기열과 스택을 생각하십시오.

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

편집 : 두 번째 문장을 더 정확하게 말하면 "추가" 는 기본 구현에 관계없이 목록 끝에 무언가를 추가한다는 것을 분명히 의미 합니다. "푸시"될 때 새 요소가 추가되는 위치가 명확하지 않습니다. 스택에 밀어 넣는 것은 "맨 위"에 놓이지 만 실제로 기본 데이터 구조로 들어가는 위치는 구현에 따라 완전히 다릅니다. 반면 대기열을 밀면 끝까지 추가됩니다.


4
이 튜토리얼은 단순히 끝에서 밀고 터지는 것을 제안하는 것 같습니다. "목록 메소드를 사용하면 목록을 스택으로 매우 쉽게 사용할 수 있습니다. 마지막으로 추가 된 요소는 검색된 첫 번째 요소입니다. 스택 맨 위에 항목을 추가하려면 append ()를 사용하고 스택 맨 위에서 항목을 검색하려면 명시 적 색인없이 pop ()을 사용하십시오. "
Uri

110
"푸시"는 결코 앞에 추가하는 것을 의미하지 않습니다. 제정신이 작성한 스택의 모든 구현은 스택의 맨 아래 (시작)가 아니라 스택의 맨 위 (끝)에 "푸시"됩니다.
Kip

4
보정 : 모든 * 배열 기반 구현. 연결리스트 구현은 헤드로 밀려날 것이다.
Kip

16
자바 스크립트 push는 끝에 추가합니다.
Kobi

2
아니요, list.pop의미 를 고려 list.append하면 스택으로 볼 때 요소를 목록으로 푸시합니다.
fortran

10

목록에 요소를 추가하기 때문에? 푸시는 일반적으로 스택을 참조 할 때 사용됩니다.


7
목록은 스택이 될 수 있습니다. :-)
Jason Baker

@JasonBaker리스트를 사용하여 스택을 구현할 수 있지만 list == stack을 의미하지는 않습니다. 원하는 경우 대기열을 사용하여 스택을 구현할 수도 있습니다. (끔찍하게 비효율적이지만 가능합니다!)
Mark E. Haase

혼란은 실제로 스택에 목록과 같이 "시작"또는 "종료"가 아니라 "상단"과 "하단"이라는 사실에서 비롯됩니다. 스택에 추가한다는 것은 요소를 맨 위에 놓고 "밀어내는"것을 의미합니다. 전면의 "푸시"는 의미가 없습니다 (적어도 언어 적으로는 아님). 더 혼란스럽게 만들기 위해 C ++은 "push_front"및 "push_back"을 사용합니다.
JesperE

9

"append"는 직관적으로 "목록 끝에 추가"를 의미하기 때문입니다. "푸시 (push)"라고 불렀다면, 꼬리 나 목록의 머리에 물건을 추가 할 것인지 불분명합니다.


12
작업이 있기 때문에 이치에 맞지 않습니다 pop. 이후 pushpop일반적으로 스택 작업하고 함께 가서, 그들이 목록의 동일한 끝에서 작동 것으로 예상한다.
jamesdlin

7

공식적인 대답은 아니지만 (언어 사용에 근거한 추측) 파이썬은 목록을 스택으로 사용할 수 있습니다 (예 : 튜토리얼의 5.1.1 섹션 ). 그러나 목록은 여전히 ​​모든 목록 중 하나이므로 둘 다에 공통적 인 연산은 스택 용어 (즉, 푸시)가 아닌 목록 용어 (즉, 추가)를 사용합니다. 팝 연산은 목록에서 일반적이지 않기 때문에 ( 'removeLast'를 사용할 수는 있었지만) pop ()을 정의했지만 push ()는 정의하지 않았습니다.


3

좋아, 개인적인 의견은 여기 있지만 Append와 Prepend는 세트에서 정확한 위치를 암시합니다.

Push와 Pop은 실제로 어떤 세트의 끝에 적용 할 수있는 개념입니다 ... 일관성이있는 한 ... 어떤 이유로 나에게 Push ()는 세트...


3
그것을 가져 왔으므로 배열에 .append () 함수가있는 경우 왜 대응하는 pre.prepend () 함수가 없습니까? .insert (0, val)을 사용하여 앞에 붙일 수는 있지만 해당 .delete (pos, val) 함수가 없기 때문에 당황합니다. 참조 : docs.python.org/2/library/array.html
MarkHu

3

참고로, 푸시 방법이있는 목록을 만드는 것은 그리 어렵지 않습니다.

>>> 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 append를 사용하면 결과 데이터 세트는 (B, C, D, A)

편집 : 와우, 거룩한 pedantry.

필자의 예제에서 목록의 어느 부분이 맨 위인지 어떤 부분이 맨 아래인지 분명하다고 가정합니다. 여기에서 우리 대부분이 왼쪽에서 오른쪽으로 읽는다고 가정하면 모든 목록의 첫 번째 요소는 항상 왼쪽에 있습니다.


1
사실이 아닙니다. 팝은 목록이 아니라 목록의 끝에서 제거합니다.
fortran

4
링크 한 페이지를 읽으십시오. 푸시는 스택 상단으로 푸시하는 것으로 정의됩니다. 어느 쪽이 "상단"인지는 구현에 달려 있습니다. 어레이 기반 스택에서 푸시는 어레이의 끝으로 밉니다. 연결된 목록 기반 스택에서 푸시는 처음으로 푸시됩니다.
Kip

0

아마도 원래 버전의 Python ( C Python)이 C ++이 아닌 C로 작성 있습니다.

물건을 무언가 뒤에 밀어 넣어 목록을 만든다는 생각은 아마도 그것들을 덧붙이려는 생각만큼 잘 알려져 있지 않을 것입니다.


두 번째 부분은 좋은 대답입니다. 그러나 이것이 C / C ++로 구현되는 것과 어떤 관련이 있습니까?
Jason Baker

@Jason : C ++의 STL에서 push_back ()은 목록에 추가하는 방법입니다. 나는 당신이 C ++에서 일하고 있다면 목록을 만드는 아이디어가 아마도 팝업 될 것이라는 메타 아이디어를 전달하려고했습니다. 말이 되나요?
풀기

연속 배열 (C ++의 벡터, Python의 목록, Perl의 배열)로 구현 된 목록 유형이있는 경우 "푸시"가 새 요소를 끝에 배치하는 것이 좋습니다. Perl 4는 "push"와 "pop"을 파이썬의 append / pop 및 C ++의 push_back / pop_back과 같은 배열의 함수로 가정했으며 STL이 C ++에 공식적으로 제안되기 훨씬 전에주의해야합니다. 따라서 C ++의 STL과는 아무런 관련이 없어서 새로운 것을 이해합니다.
Andrew Dalke

내가 Perl 배경에서 파이썬을 배우는 것을 놓친 것 중 하나는 내장 된 push (), pop (), shift () 및 unshift () 연산을 사용하여 동일한 요소의 양쪽 끝에서 요소를 추가 / 제거하는 기능입니다 배열 . "Stackish"클래스 또는 "Queueish"클래스에서 Python 목록을 쉽게 래핑 할 수 있지만 한 번에 두 가지를 모두 수행하는 것은 쉽지 않습니다 (또는 효율적).
Peter

-2

푸시 앤 팝은 카페테리아 또는 뷔페에서 접시 또는 쟁반 더미의 은유의 관점에서 의미가 있습니다. 특히 아래에 스프링이있어 상단 접시가 (이론적으로는 다소 ...) 홀더가있는 홀더 유형의 것 아래에 접시가 몇 개 있더라도 같은 장소에 있습니다.

트레이를 제거하면 스프링의 무게가 약간 줄어들고 스택이 약간 튀어 나오며, 플레이트를 다시 넣으면 스택이 아래로 밀립니다. 따라서 목록을 스택으로 생각하고 마지막 요소를 최상위로 생각하면 혼동하지 않아도됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.