목록에서 Python append () 대 + 연산자가 다른 결과를 제공하는 이유는 무엇입니까?


113

왜이 두 작업은 (DO append()RESP. +) 다른 결과를?

>>> 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, [...]]
>>> 

마지막 경우에는 실제로 무한 재귀가 있습니다. c[-1]그리고 c동일합니다. +수술 과 다른 이유는 무엇 입니까?


1
가능한 새로운 질문에 대한 모든면에서 : 나는 그것을 깨끗하게 유지하기 위해 원래 질문으로 롤백했습니다 (스레드 당 1 질문, SO FAQ 참조). 새로운 질문을하거나 각 답변 아래의 댓글 스레드에서 후속 질문을하십시오. 참고 : 편집 내용은 손실되지 않습니다. 기록을 클릭하면 새 질문에 복사 / 붙여 넣기 할 수 있습니다.
Abel


그것은 다른 ans를 제공하는 것 같지만 그렇지 않습니다. + 연산자를 사용하여 값을 추가하려면 [] 기호를 사용하십시오. c + = [c]는 추가와 동일한 결과를 제공합니다.
Sharif Chowdhury

@SharifChowdhury 나는 당신이 같은 결과를 얻을 것이라고 믿습니다
신뢰도

답변:


142

"이유"를 설명하려면 :

+작업 은 원래 배열에 배열 요소를 추가합니다 . 이 array.append작업은 배열 (또는 임의의 객체)을 원래 배열의 끝에 삽입하여 해당 지점에서 self 에 대한 참조를 생성 합니다 (따라서 무한 재귀).

여기서 차이점은 + 연산 은 요소를 연결하여 배열을 추가 할 때 특정 적으로 작동한다는 것입니다 (다른 것처럼 오버로드 됨, 시퀀스에 대한 이 장 참조 ). 그러나 append-method는 문자 그대로 사용자가 요청하는 작업을 수행합니다. 요소를 가져 오는 대신 사용자가 제공 한 오른쪽 (배열 또는 다른 개체)에 개체를 추가합니다.

대안

extend()+ 연산자와 유사한 역할을하는 함수를 사용하려는 경우 사용 합니다 (다른 사용자도 여기에 표시됨). 반대의 경우는 현명하지 않습니다. 목록에 대해 + 연산자를 사용하여 추가를 모방 하는 것입니다 (이유에 대한 이전 링크 참조 ).

작은 역사

재미로, 약간의 역사 : 1993 년 2 월 에 파이썬 에서 배열 모듈탄생 한 것입니다 . 놀라 울 수도 있지만 배열은 시퀀스와 목록이 등장한 후에 추가되었습니다.


2
나는 항상 정확한 정보를 찬성하기 때문에 +1합니다. 공식 문서에 대한 링크는 항상 플러스입니다!
jathanism

10
"왜"의 또 다른 부분 : 정상적인 사람들 +은 대칭 이되기를 기대 합니다. 목록과 목록을 연결합니다.
Beni Cherniavsky-Paskin 2010 년

1
+1, Good point Beni ( "rh 쪽의 개체가 lh 쪽의 배열에 추가됩니다"라고 말하는 것이 "정상"이라고 생각할 수 있지만 개인적으로 현재 동작이 더 합리적이라고 생각합니다).
Abel

요소가 단일 문자열 인 경우, 예 : s = 'word', l = [ 'this', 'is']. 그러면 l.append (s)와 l + s가 같아야합니다. 나 맞아?
user3512680

23

연결 연산자 +는 목록에 적용될 때 두 피연산자의 모든 요소를 ​​포함하는 새 목록을 반환하는 이진 중위 연산자입니다. list.append()방법은이다 mutatorlist자사의 단일 추가 object(특정 예 목록에 인수를 c피사체) list. 귀하의 예에서 이것은 c자체에 대한 참조를 추가합니다 (따라서 무한 재귀).

'+'연결의 대안

list.extend()메서드는 sequence인수를 subject와 연결하는 mutator 메서드이기도합니다 list. 특히 sequence반복 순서로 의 각 요소를 추가합니다 .

제쳐두고

연산자이기 때문에 +표현식의 결과를 새 값으로 반환합니다. 비체 인 mutator메서드 이기 때문에 list.extend()주제 목록을 제자리에서 수정하고 아무것도 반환하지 않습니다.

배열

위의 Abel의 답변이 목록, 시퀀스 및 배열에 대한 토론을 혼합하여 야기 할 수있는 잠재적 혼란 때문에 이것을 추가했습니다. Arrays정수 데이터 유형의 배열을 저장하는보다 효율적인 방법으로 시퀀스 및 목록 뒤에 Python에 추가되었습니다. arrays와 혼동하지 마십시오 lists. 그들은 동일하지 않습니다.

로부터 배열 문서 :

배열은 시퀀스 유형이며 목록에 저장된 객체 유형이 제한된다는 점을 제외하면 목록과 매우 유사하게 작동합니다. 유형은 단일 문자 인 유형 코드를 사용하여 객체 생성시 지정됩니다.


18

append목록에 요소를 추가하고 있습니다. 새 목록으로 목록을 확장하려면을 사용해야 extend합니다.

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

4
작업이 동일하지 않기 때문에 결과가 다른 이유 가 분명하다고 생각했습니다 ! 그것은 그렇게 나타나는 경우 +extend다른 결과를 우리가 생각하는 무언가가 거라고.
SilentGhost 2010 년

1
+1 : "왜"질문을 싫어하는 이유 : append그리고 +다릅니다. 그게 그 이유입니다. 나는이 대답이 더 좋은 일을 제공하기 때문에 좋아합니다.
S.Lott

이 사이트는 질문에 대한 답변에 대한 것이 아닙니까? 사람들은 PHP가 PHP라고 불리는 이유와 __lt__Python에서 오버로드 할 수없는 이유를 묻습니다 (현재는 가능합니다). 왜 질문은 가장 필수적인 질문이지만 종종 대답하기 가장 까다로운 질문입니다. 매뉴얼에 대한 포인터가 아니라 본질을 요청합니다. 그리고 물론 : 만약 당신이 질문을 싫어한다면 (나는 가장 싫어함), 대답하지 마세요 ;-)
Abel

더 데모를 들어, 어쩌면 보여 c += [c]c.append(c[:])도.
ephemient

2
@Abel : 왜 a+b != a*b? 그들은 다른 작업입니다. 그게 답입니다. "왜"는 "어떻게 제대로 추가 할 수 있습니까?"와 같은 다른 질문만큼 도움이되지 않습니다. 또는 "무한 재귀로 이어지는이 추가의 문제점은 무엇입니까?" "X를 어떻게해야하나요"또는 "X를했을 때 무엇이 ​​잘못 되었나요?"라는 질문이 있습니까? 또는 "X 대신 무엇을해야합니까?"는 다른 사람이 배우는 데 도움이되지만 집중적이고 유용하며 실행 가능한 답변을 제공 할 것입니다.
S.Lott

8

Python 목록은 이기종이며 동일한 목록의 요소는 모든 유형의 객체가 될 수 있습니다. 표현식 : 목록에 무엇이든지 c.append(c)객체를 추가 c합니다. 이 경우 목록 자체를 목록의 구성원으로 만듭니다.

표현식은 c += c두 개의 목록을 함께 추가하고 그 결과를 변수에 할당합니다 c. 오버로드 된 +연산자는 목록에 정의되어 내용이 첫 번째 목록의 요소와 두 번째 목록의 요소 인 새 목록을 만듭니다.

그래서 이것들은 디자인에 따라 다른 일을하는 데 사용되는 실제로 다른 표현입니다.


7

당신이 찾고있는 방법은 extend()입니다. 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

설명서를 참조하십시오 .

list.append (x)

  • 목록 끝에 항목을 추가하십시오. a [len (a) :] = [x]와 같습니다.

list.extend (L)-주어진 목록의 모든 항목을 추가하여 목록을 확장합니다. a [len (a) :] = L과 같습니다.

c.append(c)c를 요소 로 자체에 "추가" 합니다. 목록은 참조 유형이므로 재귀 데이터 구조를 만듭니다.

c += cc의 요소를 cextend(c)추가하는와 동일합니다 .

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