Python(또는 불변 데이터 유형)에서 튜플이 필요한 이유는 무엇입니까?
저는 몇 가지 파이썬 튜토리얼(예를 들어, 파이썬으로 다이빙)과 Python.org 의 언어 참조를 읽었습니다. - 언어에 튜플이 필요한 이유를 모르겠습니다.
튜플은 목록이나 집합에 비해 메서드가 없으며, 튜플을 정렬하기 위해 집합이나 목록으로 변환해야 한다면 태플을 사용하는 이유가 무엇입니까?
불변성?
변수가 원래 할당되었을 때와 메모리의 다른 위치에 있는지 여부에 대해 관심을 갖는 이유는 무엇입니까?파이썬의 불변성에 대한 이 전체 비즈니스는 지나치게 강조된 것 같습니다.
C/C++에서 포인터를 할당하고 유효한 메모리를 가리킨다면 주소를 사용하기 전에 null이 아닌 한 주소가 어디에 있는지 신경 쓰지 않습니다.
변수를 참조할 때마다 포인터가 여전히 원래 주소를 가리키고 있는지 여부를 알 필요가 없습니다.저는 null을 확인하고 사용합니다(또는 사용하지 않습니다).
파이썬에서 문자열(또는 튜플)을 x에 할당한 다음 문자열을 수정하면 원래 개체인지 여부가 왜 중요합니까?변수가 제 데이터를 가리키는 한, 그것이 중요한 전부입니다.
>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167
x
여전히 제가 원하는 데이터를 참조하는데, 왜 그 ID가 같은지 다른지에 대해 신경을 써야 합니까?
불변 객체는 상당한 최적화를 허용할 수 있습니다. 이것이 아마도 문자열이 자바에서 불변이며, 꽤 별개로 개발되었지만 파이썬과 거의 같은 시기에 개발되었으며, 진정한 기능을 하는 언어에서는 거의 모든 것이 불변인 이유일 것입니다.
특히 Python에서는 불변의 변수만 해시 가능합니다(따라서 집합의 멤버 또는 사전의 키).다시 말하지만, 이것은 "실질적인" 것 이상의 것을 제공합니다. (완전하게 변형 가능한 개체를 저장하는 적절한 해시 테이블을 설계하는 것은 악몽입니다. 해시하자마자 모든 것의 복사본을 가져오거나 마지막으로 참조한 이후로 개체의 해시가 변경되었는지 확인하는 악몽입니다.)
최적화 문제의 예:
$ python -mtimeit '["fee", "fie", "fo", "fum"]'
1000000 loops, best of 3: 0.432 usec per loop
$ python -mtimeit '("fee", "fie", "fo", "fum")'
10000000 loops, best of 3: 0.0563 usec per loop
위의 답변 중 어떤 것도 Python을 처음 접하는 많은 사람들이 완전히 이해하지 못하는 것처럼 보이는 튜플 대 리스트의 실제 문제를 지적하지 않습니다.
튜플과 목록은 서로 다른 용도로 사용됩니다.동종 데이터를 저장하는 목록입니다.다음과 같은 목록이 있어야 합니다.
["Bob", "Joe", "John", "Sam"]
목록을 올바르게 사용하는 이유는 목록이 모두 동질적인 유형의 데이터, 특히 사람의 이름이기 때문입니다.그러나 다음과 같은 목록을 작성합니다.
["Billy", "Bob", "Joe", 42]
그 목록은 한 사람의 전체 이름과 나이입니다.그것은 한 종류의 데이터가 아닙니다.해당 정보를 저장하는 올바른 방법은 튜플 또는 개체에 있습니다.몇 가지 예를 들어 보겠습니다.
[("Billy", "Bob", "Joe", 42), ("Robert", "", "Smith", 31)]
튜플과 리스트의 불변성과 불변성은 주요 차이점이 아닙니다.목록은 파일, 이름, 개체 등 동일한 종류의 항목을 나열한 목록입니다.튜플은 서로 다른 유형의 개체를 그룹화한 것입니다.이들은 용도가 다르며, 많은 파이썬 코더들은 튜플이 무엇을 위한 것인지 목록을 남용합니다.
제발 하지마.
편집:
이 블로그 게시물은 제가 왜 이것을 저보다 더 잘 생각하는지 설명해주는 것 같습니다.
튜플을 정렬하기 위해 집합이나 목록으로 변환해야 한다면 태플을 처음부터 사용하는 이유는 무엇입니까?
이 특별한 경우에는, 아마도 요점이 없을 것입니다.이는 문제가 되지 않습니다. 튜플 사용을 고려할 수 있는 경우가 아니기 때문입니다.
당신이 지적했듯이, 튜플은 불변입니다.불변 유형을 갖는 이유는 튜플에 적용됩니다.
- 복사 효율성: 불변 객체를 복사하는 대신 별칭을 지정할 수 있습니다(변수를 참조에 추가).
- 비교 효율성: 참조별 복사를 사용하는 경우 내용이 아닌 위치를 비교하여 두 변수를 비교할 수 있습니다.
- 내부: 불변 값의 복사본을 최대 한 개까지 저장해야 합니다.
- 동시 코드에서 불변 객체에 대한 액세스를 동기화할 필요가 없습니다.
- 항상 정확성: 일부 값은 변경할 수 없습니다.이것이 불변의 주된 이유입니다.
특정 Python 구현이 위의 모든 기능을 사용하지 않을 수 있습니다.
사전 키는 불변이어야 합니다. 그렇지 않으면 키 개체의 속성을 변경하면 기본 데이터 구조의 불변성이 무효화될 수 있습니다.따라서 튜플은 잠재적으로 키로 사용될 수 있습니다.이것은 항상 정확성의 결과입니다.
Dive Into Python의 "튜플 소개"도 참조하십시오.
때때로 우리는 사물을 사전 키로 사용하는 것을 좋아합니다.
최근 튜플(2.6+)이 증가한 것은 당연합니다.index()
그리고.count()
방법들
저는 항상 동일한 기본 데이터 구조(어레이)에 대해 두 가지 유형을 완전히 분리하는 것이 어색한 설계이지만 실제로는 문제가 되지 않습니다. (모든 언어에는 사마귀가 있고, 파이썬도 포함되어 있지만, 이것은 중요한 것은 아닙니다.)
변수가 원래 할당되었을 때와 메모리의 다른 위치에 있는지 여부에 대해 관심을 갖는 이유는 무엇입니까?파이썬의 불변성에 대한 이 전체 비즈니스는 지나치게 강조된 것 같습니다.
이것들은 다른 것들입니다.가변성은 메모리에 저장된 위치와 관련이 없습니다. 변경할 수 없다는 것을 의미합니다.
Python 객체는 생성된 후, 변경 가능 여부와 상관없이 위치를 변경할 수 없습니다. (더 정확하게는 id()의 값은 변경할 수 없습니다. 실제로는 동일한 것입니다.)가변 객체의 내부 저장소는 변경될 수 있지만, 이는 숨겨진 구현 세부 사항입니다.
>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167
이는 변수를 수정("변조")하는 것이 아니라 동일한 이름을 가진 새 변수를 만들고 이전 변수를 삭제하는 것입니다.돌연변이 작업과 비교:
>>> a = [1,2,3]
>>> id(a)
3084599212L
>>> a[1] = 5
>>> a
[1, 5, 3]
>>> id(a)
3084599212L
다른 사람들이 지적했듯이, 이를 통해 어레이를 사전 및 불변성이 필요한 기타 데이터 구조의 키로 사용할 수 있습니다.
사전 키가 완전히 변경될 필요는 없습니다.키로 사용되는 부분만 변경할 수 있으면 됩니다. 일부 용도에서는 이것이 중요한 차이점입니다.예를 들어 사용자를 나타내는 클래스가 있을 수 있습니다. 클래스는 고유한 사용자 이름으로 동일성과 해시를 비교합니다.그런 다음 "사용자가 로그인했습니다" 등의 다른 가변 데이터를 클래스에 걸 수 있습니다.이것은 동등성이나 해시에 영향을 미치지 않으므로 사전의 키로 사용할 수 있으며 완벽하게 유효합니다.이것은 Python에서 너무 일반적으로 필요하지 않습니다. 몇몇 사람들이 키가 "불변"이어야 한다고 주장했기 때문에 저는 단지 부분적으로만 정확하다고 지적했습니다.하지만 저는 C++ 지도와 세트에 이것을 여러 번 사용했습니다.
Guido는 의견을 제시하면서 완전히 수용/인정되지 않은 의견을 제시된 의견은 다음과 같습니다."목록은 동종 데이터에 대한 것이고, 튜플은 이종 데이터에 대한 것입니다."물론 많은 반대자들은 이것을 목록의 모든 요소가 동일한 유형이어야 한다는 의미로 해석했습니다.
저는 다른 사람들이 과거에 했던 것과 다르지 않게 다르게 보는 것을 좋아합니다.
blue= 0, 0, 255
alist= ["red", "green", blue]
!= 유형(list[1]!= 유형(list[2])이라도 목록은 동종으로 간주됩니다.
요소의 순서를 변경할 수 있고 코드에 문제가 없을 경우(예: "정렬되어야 함") 목록이 사용되어야 합니다.그렇지 않다면 (튜플에서처럼)blue
위), 그러면 튜플을 사용해야 합니다.
그들은 그들이 통과한 물체가 변형되지 않도록 발신자에게 보증하기 때문에 중요합니다.이 작업을 수행할 경우:
a = [1,1,1]
doWork(a)
발신자는 통화 후 a의 가치에 대한 보장이 없습니다.하지만,
a = (1,1,1)
doWorK(a)
이제 당신은 이 코드의 발신자 또는 독자로서 a가 동일하다는 것을 알고 있습니다.이 시나리오에서는 항상 목록의 복사본을 만들고 통과할 수 있지만, 이제는 더 의미 있는 언어 구조를 사용하는 대신 주기를 낭비하고 있습니다.
당신은 이것에 대한 약간의 토론을 위해 여기를 볼 수 있습니다.
질문(및 후속 설명)은 할당 중에 ID()가 변경되는지 여부에 초점을 맞춥니다.차이 자체보다는 불변 객체 대체와 가변 객체 수정 간의 차이의 후속 효과에 초점을 맞추는 것이 아마도 최선의 접근법은 아닐 것입니다.
계속하기 전에 아래에 설명된 동작이 Python에서 기대하는 동작인지 확인하십시오.
>>> a1 = [1]
>>> a2 = a1
>>> print a2[0]
1
>>> a1[0] = 2
>>> print a2[0]
2
이 경우 a1만 새 값이 할당되었음에도 불구하고 a2의 내용이 변경되었습니다.다음과 비교해 보십시오.
>>> a1 = (1,)
>>> a2 = a1
>>> print a2[0]
1
>>> a1 = (2,)
>>> print a2[0]
1
후자의 경우, 우리는 전체 목록의 내용을 업데이트하는 대신 전체 목록을 교체했습니다.튜플과 같은 불변 유형의 경우 이 동작만 허용됩니다.
이것이 왜 중요합니까?받아쓰기가 있다고 가정해 보겠습니다.
>>> t1 = (1,2)
>>> d1 = { t1 : 'three' }
>>> print d1
{(1,2): 'three'}
>>> t1[0] = 0 ## results in a TypeError, as tuples cannot be modified
>>> t1 = (2,3) ## creates a new tuple, does not modify the old one
>>> print d1 ## as seen here, the dict is still intact
{(1,2): 'three'}
튜플을 사용하면 사전의 키가 "아래에서" 다른 값으로 해시되는 항목으로 변경되지 않습니다.이는 효율적인 구현을 위해 매우 중요합니다.
언급URL : https://stackoverflow.com/questions/2174124/why-do-we-need-tuples-in-python-or-any-immutable-data-type
'programing' 카테고리의 다른 글
Android API 버전을 프로그래밍 방식으로 검색하는 중 (0) | 2023.07.18 |
---|---|
NumPy에서 NaN에 대한 빠른 확인 (0) | 2023.07.18 |
Matlab의 tic 및 toc 함수에 해당하는 파이썬은 무엇입니까? (0) | 2023.07.18 |
하위 항목에 값이 포함되어 있는지 여부를 Firebase 쿼리 (0) | 2023.07.18 |
ASP.NET 코어에서 Swagger의 기본 URL을 변경하는 방법 (0) | 2023.07.18 |