Python tạo một từ điển danh sách


214

Tôi muốn tạo một từ điển có giá trị là danh sách. Ví dụ:

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

Nếu tôi làm:

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

Tôi nhận được KeyError, vì d [...] không phải là danh sách. Trong trường hợp này, tôi có thể thêm đoạn mã sau sau khi gán a để khởi tạo từ điển.

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

Có cách nào tốt hơn để làm điều này? Hãy nói rằng tôi không biết chìa khóa tôi sẽ cần cho đến khi tôi ở forvòng lặp thứ hai . Ví dụ:

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

Một sự thay thế sau đó sẽ được thay thế

d[scope_item].append(relation)

với

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

cách tốt nhất để xử lý này là gì? Lý tưởng nhất, việc nối thêm sẽ "chỉ hoạt động". Có cách nào để diễn đạt rằng tôi muốn có một từ điển danh sách trống, ngay cả khi tôi không biết mọi khóa khi lần đầu tiên tạo danh sách?

Câu trả lời:


278

Bạn có thể sử dụng defaultdict :

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> a = ['1', '2']
>>> 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'])]

1
Các từ điển khác trong collectionsmô-đun cũng hoạt động theo cách này, ví dụ collections.OrderedDict.
txsaw1

2
Oh. Điều đó thật tuyệt. Và bạn không phải khởi tạo thành '= []'. Đồ tốt!
Wilmer E. Henao

1
NameError: name 'a' is not defined
S Andrew

51

Bạn có thể xây dựng nó với danh sách hiểu như thế này:

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

Và đối với phần thứ hai của câu hỏi của bạn, hãy sử dụng 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])]

32

Bạn có thể sử dụng 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']}

Hàm có tên khá kỳ lạ setdefaultnói "Nhận giá trị bằng khóa này hoặc nếu khóa đó không có, hãy thêm giá trị này và sau đó trả lại."

Như những người khác đã chỉ ra defaultdictmột cách đúng đắn, là một lựa chọn tốt hơn và hiện đại hơn. setdefaultvẫn hữu ích trong các phiên bản cũ hơn của Python (trước 2.5).


2
Điều này hoạt động, nhưng nó thường được ưu tiên sử dụng defaultdict khi nó khả dụng.
David Z

@David, yeah, setdefault không phải là thiết kế tuyệt vời nhất, xin lỗi - nó hầu như không phải là sự lựa chọn tốt nhất. Tôi nghĩ rằng chúng tôi (những người tham gia Python) đã lấy lại danh tiếng tập thể của chúng tôi bằng các bộ sưu tập.defaultdict, mặc dù ;-).
Alex Martelli

@DavidZ, setdefault khác với defaultdict, vì nó linh hoạt hơn: khác, làm thế nào để bạn chỉ định các giá trị mặc định khác nhau cho các khóa từ điển khác nhau?
Alex Gidan

@AlexGidan Điều đó đúng, nhưng không đặc biệt liên quan đến câu hỏi này.
David Z

Câu trả lời này cũng hữu ích khi bạn cần OrderedDict và giá trị mặc định.
nimcap

2

Câu hỏi của bạn đã được trả lời, nhưng IIRC bạn có thể thay thế các dòng như:

if d.has_key(scope_item):

với:

if scope_item in d:

Đó là, dtài liệu tham khảo d.keys()trong xây dựng đó. Đôi khi defaultdictkhông phải là tùy chọn tốt nhất (ví dụ: nếu bạn muốn thực thi nhiều dòng mã sau khi được elseliên kết với ở trên if) và tôi thấy incú pháp dễ đọc hơn.


2

Cá nhân, tôi chỉ sử dụng JSON để chuyển đổi mọi thứ thành chuỗi và ngược lại. Chuỗi tôi hiểu.

import json
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
mydict = {}
hash = json.dumps(s)
mydict[hash] = "whatever"
print mydict
#{'[["yellow", 1], ["blue", 2], ["yellow", 3], ["blue", 4], ["red", 1]]': 'whatever'}

1

cách dễ dàng là:

a = [1,2]
d = {}
for i in a:
  d[i]=[i, ]

print(d)
{'1': [1, ], '2':[2, ]}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.