2009-06-06 6 views
167

목록을 값으로하는 사전을 만들고 싶습니다. 예를 들면 :Python 목록 사전 작성하기

{ 
    1: ['1'], 
    2: ['1','2'], 
    3: ['2'] 
} 

내가 할 경우 : d는 [...] 목록이 아니기 때문에

d = dict() 
a = ['1', '2'] 
for i in a: 
    for j in range(int(i), int(i) + 2): 
     d[j].append(i) 

내가하는 KeyError를 얻을. 이 경우 사전을 초기화하기 위해 a를 할당 한 후 다음 코드를 추가 할 수 있습니다.

for x in range(1, 4): 
    d[x] = list() 

더 좋은 방법이 있나요? 두 번째로 for 루프가 될 때까지 필자가 필요로하는 키를 모를 것이라고 말합니다. 예를 들어 :

class relation: 
    scope_list = list() 
... 
d = dict() 
for relation in relation_list: 
    for scope_item in relation.scope_list: 
     d[scope_item].append(relation) 

대안은 다음

if d.has_key(scope_item): 
    d[scope_item].append(relation) 
else: 
    d[scope_item] = [relation,] 

이 문제를 처리하는 가장 좋은 방법은 무엇입니까와

d[scope_item].append(relation) 

를 대체 할 것인가? 이상적으로, appending은 "그냥 작동"합니다. 목록을 처음 만들 때 모든 키를 모를지라도 빈 목록 사전을 표시 할 수있는 방법이 있습니까?

답변

211

당신이 사용할 수있는 사용 defaultdict :

>>> from collections import defaultdict 
>>> d = defaultdict(list) 
>>> for i in a: 
... for j in range(int(i), int(i) + 2): 
...  d[j].append(i) 
... 
>>> d 
defaultdict(<type 'list'>, {1: ['1'], 2: ['1', '2'], 3: ['2']}) 
>>> d.items() 
[(1, ['1']), (2, ['1', '2']), (3, ['2'])] 
+0

'collections' 모듈 아래의 다른 사전도'collections.OrderedDict'처럼이 방법으로 작동합니다. – txsaw1

+1

오. 이것은 위대합니다. 그리고 '= []'로 초기화 할 필요는 없습니다. 좋은 물건! –

21

사용 setdefault는 :

d = dict() 
a = ['1', '2'] 
for i in a: 
    for j in range(int(i), int(i) + 2): 
     d.setdefault(j, []).append(i) 

print d # prints {1: ['1'], 2: ['1', '2'], 3: ['2']} 

오히려 이상한 이름의 setdefault 기능 "이 키를 사용하여 값을 취득하거나 키가없는 경우,이 값을 추가하고 다음을 반환합니다."라고

편집 : 다른 사람들이 올바르게 지적한 바대로 defaultdict은 더 좋고 현대적인 선택입니다. setdefault은 이전 버전의 Python (2.5 이전)에서 여전히 유용합니다.

+2

이 방법이 유용하지만 일반적으로 사용 가능한 경우 defaultdict를 사용하는 것이 좋습니다. –

+0

@David, 예, setdefault는 가장 화려한 디자인이 아니 었습니다. 미안합니다. 거의 최고의 선택이 아닙니다. 필자 (우리는 파이썬 커미터들)가 collects.defaultdict를 사용하여 우리의 공동 명성을 되찾았다 고 생각합니다. ;-). –

+0

@DavidZ, setdefault는보다 유연하기 때문에 defaultdef와 다르다. otherwhise, 어떻게 다른 사전 키에 다른 기본값을 지정합니까? –

37

이 같은 지능형리스트로를 구축 할 수 있습니다 :

>>> dict((i, range(int(i), int(i) + 2)) for i in ['1', '2']) 
{'1': [1, 2], '2': [2, 3]} 

그리고 질문의 두 번째 부분에 대한 defaultdict

>>> from collections import defaultdict 
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)] 
>>> d = defaultdict(list) 
>>> for k, v in s: 
     d[k].append(v) 

>>> d.items() 
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])] 
1

귀하의 질문에 이미 답변되어 있지만 IIRC는 귀하가 리 같은 NES :

입니다
if scope_item in d: 

, d 참조 d.keys() 그 건설 :와

if d.has_key(scope_item): 

. 때로는 defaultdict이 최상의 옵션이 아닙니다 (예를 들어, 위의 if과 연결된 else 뒤에 여러 줄의 코드를 실행하려는 경우). in 구문을 더 쉽게 읽을 수 있습니다.