2011-12-18 54 views
14

Từ một hàm khác, tôi có các bộ từ như thế này ('falseName', 'realName', positionOfMistake), ví dụ: ('Milter', 'Miller', 4). tôi cần phải viết một hàm mà làm cho một cuốn từ điển như thế này:Từ điển python của từ điển

D={realName:{falseName:[positionOfMistake], falseName:[positionOfMistake]...}, 
    realName:{falseName:[positionOfMistake]...}...} 

Chức năng phải mất một từ điển và một tuple như trên, như các đối số.

Tôi đã suy nghĩ một cái gì đó như thế này cho một sự khởi đầu:

def addToNameDictionary(d, tup): 
    dictionary={} 
    tup=previousFunction(string) 
    for element in tup: 
     if not dictionary.has_key(element[1]): 
      dictionary.append(element[1]) 
    elif: 
     if ... 

Nhưng nó không phải đang làm việc và tôi loại stucked đây.

+0

bạn đang thụt đầu dòng là sai. và chính xác thì những gì không hiệu quả? – yurib

+2

'tup' trong tham số đang bị thổi bay bởi dòng 'tup = previ ..'. Mã có vẻ như bạn không giữ bức tranh lớn trong đầu. Tôi nghĩ dừng lại, bước ra khỏi máy tính, hít một hơi thật sâu, đi dạo, ngồi xuống, nhắm mắt lại và viết mã xuống bằng bút chì và giấy. – matiu

Trả lời

15

Nếu nó chỉ là thêm một tuple mới và bạn chắc chắn rằng không có va chạm trong từ điển bên trong, bạn có thể làm điều này:

def addNameToDictionary(d, tup): 
    if tup[0] not in d: 
     d[tup[0]] = {} 
    d[tup[0]][tup[1]] = [tup[2]] 
+3

Bài kiểm tra has_key được viết tốt hơn 'nếu tup [0] không phải trong d: ' –

+0

okay - đó có phải là sự thuận lợi không? – aweis

+1

http://stackoverflow.com/questions/1323410/has-key-or-in –

10

Sử dụng collections.defaultdict là một tiết kiệm thời gian lớn khi bạn đang xây dựng cảnh quan và không biết trước những chìa khóa bạn sẽ có.

Ở đây nó được sử dụng hai lần: cho kết quả chính tả và cho mỗi giá trị trong dict.

import collections 

def aggregate_names(errors): 
    result = collections.defaultdict(lambda: collections.defaultdict(list)) 
    for real_name, false_name, location in errors: 
     result[real_name][false_name].append(location) 
    return result 

Kết hợp điều này với mã của bạn:

dictionary = aggregate_names(previousFunction(string)) 

Hoặc để kiểm tra:

EXAMPLES = [ 
    ('Fred', 'Frad', 123), 
    ('Jim', 'Jam', 100), 
    ('Fred', 'Frod', 200), 
    ('Fred', 'Frad', 300)] 
print aggregate_names(EXAMPLES) 
8

điển của setdefault là một cách tốt để cập nhật một mục dict hiện tại nếu nó ở đó, hoặc tạo ra một mới nếu không phải tất cả trong một lần:

Kiểu vòng lặp:

Từ điển
# This is our sample data 
data = [("Milter", "Miller", 4), ("Milter", "Miler", 4), ("Milter", "Malter", 2)] 

# dictionary we want for the result 
dictionary = {} 

# loop that makes it work 
for realName, falseName, position in data: 
    dictionary.setdefault(realName, {})[falseName] = position 

nay tương đương với:

{'Milter': {'Malter': 2, 'Miler': 4, 'Miller': 4}}