2013-05-10 31 views
221

Có cách nào để đổi tên khóa từ điển, không gán lại giá trị của nó cho một tên mới và xóa khóa tên cũ; và không lặp lại thông qua khóa/giá trị dict?

Trong trường hợp OrderedDict, thực hiện tương tự, trong khi vẫn giữ vị trí của khóa đó.Đổi tên một khóa từ điển

+5

chính xác những gì bạn có ý nghĩa bởi "không có giao lại giá trị của mình cho một tên mới và loại bỏ các phím tên cũ "? theo cách tôi thấy, đó là định nghĩa đổi tên khóa và tất cả các câu trả lời dưới đây chỉ định lại giá trị và xóa tên khóa cũ. bạn vẫn chưa chấp nhận câu trả lời, vì vậy có lẽ những điều này chưa hoàn thành những gì bạn đang tìm kiếm? – dbliss

Trả lời

14

Sử dụng một tấm séc cho newkey!=oldkey, bằng cách này bạn có thể làm:

if newkey!=oldkey: 
    dictionary[newkey] = dictionary[oldkey] 
    del dictionary[oldkey] 
412

Đối với một dict thường xuyên, bạn có thể sử dụng:

mydict[new_key] = mydict.pop(old_key) 

Đối với một OrderedDict, tôi nghĩ rằng bạn phải xây dựng một hoàn toàn cái mới sử dụng hiểu.

>>> OrderedDict(zip('123', 'abc')) 
OrderedDict([('1', 'a'), ('2', 'b'), ('3', 'c')]) 
>>> oldkey, newkey = '2', 'potato' 
>>> OrderedDict((newkey if k == oldkey else k, v) for k, v in _.viewitems()) 
OrderedDict([('1', 'a'), ('potato', 'b'), ('3', 'c')]) 

Sửa đổi chính bản thân, như câu hỏi này dường như được hỏi, là không thực tế vì các phím dict thường bất biến các đối tượng như con số, chuỗi hoặc tuples. Thay vì cố gắng sửa đổi khóa, gán lại giá trị cho khóa mới và xóa khóa cũ là cách bạn có thể đạt được "đổi tên" trong python.

+0

Đối với python 3.5, tôi nghĩ 'dict.pop' là hoàn toàn khả thi cho một OrderedDict dựa trên thử nghiệm của tôi. – Daniel

+1

Không, 'OrderedDict' sẽ giữ nguyên thứ tự chèn, đó không phải là câu hỏi được đặt ra. – wim

+0

Bạn đúng, sai lầm của tôi. – Daniel

7

Bạn có thể sử dụng OrderedDict recipe này được viết bởi Raymond hettinger và sửa đổi nó để thêm một phương pháp rename, nhưng điều này sẽ là một O (N) về độ phức tạp:

def rename(self,key,new_key): 
    ind = self._keys.index(key) #get the index of old key, O(N) operation 
    self._keys[ind] = new_key #replace old key with new key in self._keys 
    self[new_key] = self[key] #add the new key, this is added at the end of self._keys 
    self._keys.pop(-1)   #pop the last item in self._keys 

Ví dụ:

dic = OrderedDict((("a",1),("b",2),("c",3))) 
print dic 
dic.rename("a","foo") 
dic.rename("b","bar") 
dic["d"] = 5 
dic.rename("d","spam") 
for k,v in dic.items(): 
    print k,v 

đầu ra:

OrderedDict({'a': 1, 'b': 2, 'c': 3}) 
foo 1 
bar 2 
c 3 
spam 5 
+0

Trông giống như một cách tiếp cận rất tốt, nhưng làm thế nào tôi có thể thêm nó vào kịch bản của tôi? – MERose

+1

@MERose Thêm tệp Python vào đâu đó trong đường dẫn tìm kiếm mô-đun của bạn và nhập 'OrderedDict' từ nó. Nhưng tôi khuyên bạn nên: Tạo một lớp kế thừa từ 'OrderedDict' và thêm phương thức' rename' vào nó. –

37

phương pháp tốt nhất trong 1 dòng:

>>> d = {'test':[0,1,2]} 
>>> d['test2'] = d.pop('test') 
>>> d 
{'test2': [0, 1, 2]} 
+2

nếu bạn có 'd = {('test', 'foo'): [0,1,2]}'? –

+1

@PetrFedosov, sau đó bạn làm 'd [('mới', 'chìa khóa')] = d.pop (('kiểm tra', 'foo'))' –

+1

Câu trả lời này đến _two năm_ sau câu trả lời của wim cho thấy chính xác điều, không có thêm thông tin. Tôi đang thiếu gì? –

0

Một vài người trước khi tôi đề cập đến .pop trick để xóa và tạo một khóa trong một lớp lót.

Cá nhân tôi thấy việc thực hiện rõ ràng hơn dễ đọc hơn:

d = {'a': 1, 'b': 2} 
v = d['b'] 
del d['b'] 
d['c'] = v 

Đoạn mã trên trả về {'a': 1, 'c': 2}

Các vấn đề liên quan