파이썬에서 사전 대 튜플을 사용하는 경우


31

구체적인 예는 파일 이름과 크기 목록입니다. 목록의 각 항목이 형식이어야하는지 {"filename": "blabla", "size": 123}아니면 그냥 형식이어야하는지 결정할 수 없습니다 ("blabla", 123). 예를 들어 크기에 액세스하는 file["size"]것이 더 설명이 필요하기 때문에 사전이 나에게 더 논리적 인 것처럼 보이지만 file[1]실제로는 확실하지 않습니다. 생각?


부록으로, 고려 튜플 풀고 - 당신은 튜플의 readabilities에 대해 걱정하는 경우, fname, file_size = file데이터가 위의 튜플이고, 멀리 할 것 file[1]와로 교체 file_size. 물론 이것은 좋은 문서에 의존합니다.
nlsdfnbch

2
어떤 데이터 구조를 구축하고 있으며 어떻게 액세스하려고합니까? (파일 이름으로? 인덱스로? 둘 다?) 그냥 끔찍한 변수 / 데이터 구조입니까, 아니면 크기뿐만 아니라 다른 항목 (/ 속성)을 추가합니까? 구조가 순서를 기억해야합니까? 크기 목록을 정렬하거나 위치별로 액세스 하시겠습니까 (예 : "top-n 가장 큰 / 가장 작은 파일")? 이에 따라 '최상의'답변은 dict, OrderedDict, 명명 된 튜플, 일반 이전 목록 또는 사용자 정의 클래스 일 수 있습니다. 더 많은 맥락이 필요합니다.
smci

답변:


78

나는 namedtuple:를 사용할 것이다

from collections import namedtuple
Filesize = namedtuple('Filesize', 'filename size')
file = Filesize(filename="blabla", size=123)

이제 가장 쉽게 읽을 수있는 형식 인 IMHO 인 file.sizefile.filename프로그램을 사용할 수 있습니다 . 참고 namedtuple는 튜플과 같은 변경 불가능한 객체를 생성하며 여기에 설명 된대로 사전보다 더 가볍습니다 .


1
고마워, 좋은 생각, 오늘 전에 그들에 대해 들어 본 적이 없습니다 (Python에서는 꽤 귀찮습니다). 질문 : 코드의 다른 곳에서 동일한 "클래스"를 약간 다르게 정의하면 어떻게됩니까? 예를 들어, 다른 소스 파일에서 동료 Bob은Filesize = namedtuple('Filesize', 'filepath kilobytes')
user949300

아주 멋진 attrs모듈을 사용 pip하거나 (찾아서 검색 할 수 있음) 명명 된 튜플과 매우 유사한 구문 편의를 제공하지만 변경 가능성을 제공 할 수는 있지만 변경할 수는 없습니다. 주요 기능상의 차이점은- attrs만든 클래스는 평범한 튜플과 동일하지 않습니다 namedtuple.
mtraceur

3
@DocBrown Python에는 선언 개념이 없습니다. class, def, 그리고 =모든 단지 이전의 용도를 덮어 씁니다. repl.it
Challenger5

@ Challenger5 : 당신은 옳습니다. 제 실수는 정답입니다 : 최신 정의 횟수, Python 런타임의 오류는 없지만 다른 변수와 여전히 유사한 동작입니다.
Doc Brown

8
참고 namedtuple본질적으로 불변 특성을 가진 새로운 유형에 대한 짧은 손 선언입니다. 이것은 "어느 A, 대답은 효과적으로 의미 tuple도 아니고 dict, 그러나 object." +1
jpmc26

18

{ "파일 이름": "blabla", "size": 123} 또는 그냥 ( "blabla", 123)

이것은 형식 / 스키마를 대역 내 또는 대역 외로 인코딩할지 여부에 대한 오래된 질문입니다.

데이터의 형식을 데이터에 표현함으로써 얻을 수있는 가독성과 이식성을 얻기 위해 일부 메모리를 교환합니다. 이 작업을 수행하지 않으면 첫 번째 필드는 파일 이름이고 두 번째 필드는 크기를 다른 곳에 유지해야합니다. 메모리는 절약되지만 가독성과 이식성이 필요합니다. 어느 회사에 더 많은 비용이 듭니까?

불변의 문제에 관해서는, 불변의 의미가 변화에 직면해도 쓸모 없다는 것을 기억하지 마십시오. 메모리를 더 확보하고 사본을 변경하고 새 사본을 사용해야한다는 의미입니다. 그것은 무료가 아니지만 종종 거래 차단기가 아닙니다. 우리는 항상 변경하기 위해 불변 문자열을 사용합니다.

다른 고려 사항은 확장 성입니다. 인코딩 형식 정보없이 데이터를 위치 적으로 만 저장하는 경우 단일 상속만으로 정죄됩니다. 이는 실제로 설정된 필드 뒤에 추가 필드를 연결하는 방법 일뿐입니다. 첫 번째와 두 번째를 같은 방식으로 정의하므로 세 번째 필드를 작성 날짜로 정의하고 형식과 여전히 호환되도록 정의 할 수 있습니다.

그러나 내가 할 수없는 일은 겹치는 필드가있는 두 개의 독립적으로 정의 된 형식을 결합하고 일부는 겹치지 않고 하나의 형식으로 저장하고 하나 또는 다른 형식에 대해서만 알고있는 것에 유용합니다.

그렇게하려면 처음부터 형식 정보를 인코딩해야합니다. "이 필드는 파일 이름입니다"라고 말해야합니다. 그렇게하면 여러 상속이 가능합니다.

상속은 객체의 컨텍스트에서만 표현되는 데 익숙하지만 객체는 데이터 형식으로 저장되므로 동일한 아이디어가 데이터 형식에 적용됩니다. 정확히 같은 문제입니다.

따라서 가장 필요할 것으로 생각되는 것을 사용하십시오. 정당하지 않은 이유를 지적 할 수 없다면 유연성에 도달합니다.


3
솔직히 말해서, 대역 내 또는 대역 외 형식을 사용하는 것이 확실하지 않은 사람은 대역 외 형식을 사용해야하는 엄격한 성능 요구 사항이 있는지 의심합니다.
Alexander-Reinstate Monica

2
@Alexander 매우 사실입니다. 대역 외 솔루션에 직면했을 때 그들이 무엇을보고 있는지 이해할 수 있도록 사람들에게 그것에 대해 가르치는 것을 선호합니다. 이진 형식은 난독 화를 위해 종종이 작업을 수행합니다. 모두가 휴대하기를 원하는 것은 아닙니다. 성능상의 이유로 실제로 중요한 경우 대역 외를 사용하기 전에 압축을 고려하십시오.
candied_orange 21시

OP는 Python을 사용하므로 성능에 대해서는 크게 신경 쓰지 않을 것입니다. 대부분의 고급 코드는 먼저 가독성을 염두에두고 작성해야합니다. 조기 최적화는 모든 악의 근원입니다.
Dagrooms

@Dagrooms는 Python을 싫어하지 않습니다. 많은 경우에 잘 작동합니다. 그러나 그렇지 않으면 나는 당신이 말한 모든 것에 동의합니다. 내 요점은 "사람들이 그렇게하는 이유입니다. 당신이 신경 쓰지 않는 이유가 여기에 있습니다."라고 말했습니다.
candied_orange

@CandiedOrange 나는 언어를 싫어하지 않고 일상 업무에서 사용합니다. 사람들이 사용하는 방식이 마음에 들지 않습니다.
Dagrooms

7

두 가지 속성이있는 클래스를 사용합니다. 또는 file.size보다 낫습니다 .file[1]file["size"]

단순한 것보다 복잡한 것이 좋습니다.


누군가 궁금한 점이있는 경우 : JSON 생성의 경우 두 가지 모두 동일하게 작동 file = Filesize(filename='stuff.txt', size=222)하며 filetup = ("stuff.txt", 222)둘 다 동일한 JSON을 생성하여 결과는 다음 json.dumps(file)json.dumps(filetup)같습니다.'["stuff.txt", 222]'
Juha Untinen

5

파일 이름이 고유합니까? 그렇다면 목록을 완전히 지우고 모든 파일에 순수한 사전을 사용할 수 있습니다. 예 (가설 웹 사이트)

{ 
  "/index.html" : 5467,
  "/about.html" : 3425,
  "/css/main.css" : 9876
}

기타...

이제 "이름"과 "크기"를 얻지 못하고 키와 값만 사용하지만 더 자연스러운 경우가 많습니다. YMMV.

당신이 경우 정말 명확성의 "크기"를 원하는, 또는 당신은 다음 파일에 대한 하나 이상의 값이 필요합니다 :

{ 
   "/index.html" : { "size": 5467, "mime_type" : "foo" },
   "/about.html" : { "size": 3425, "mime_type" : "foo" }
   "/css/main.css" : { "size": 9876, "mime_type" : "bar" }
}

0

파이썬에서 사전은 변경 가능한 객체입니다. 다른 쪽, 튜플은 불변의 객체입니다.

사전 키, 값 쌍을 자주 또는 매번 변경해야하는 경우 사용할 사전을 제안합니다.

고정 / 정적 데이터가 있다면 튜플을 사용하는 것이 좋습니다.

# dictionary define.
a = {}
a['test'] = 'first value'

# tuple define.
b = ()
b = b+(1,)

# here, we can change dictionary value for key 'test'
a['test'] = 'second'

그러나 할당 연산자를 사용하여 튜플 데이터를 변경할 수 없습니다.

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