2012-04-18 24 views
9

Tôi muốn so sánh các phần tử trong từ điển với nhau và xóa các mục theo một số tiêu chí so sánh. Và tôi rất muốn nó hiệu quả. Tôi có một chức năng có thể làm điều này, nhưng nó liên tục sao chép từ điển. Chắc chắn có một cách vượt trội:So sánh chính tả và loại bỏ các khóa tương tự một cách hiệu quả

mydict = {1:5,2:7,3:9,4:9,7:7,8:0,111:43,110:77} 

def partial_duplicate_destroyer(mydict,tolerance): 
    for key1 in mydict.keys(): 
     mydict_copy = mydict.copy() 
     for key2 in mydict_copy.keys(): 
      if key2 - tolerance < key1 < key2 + tolerance and not(key1 == key2): 
       del(mydict[key1]) 
       break 
    return mydict 

print partial_duplicate_destroyer(mydict,2) 
print partial_duplicate_destroyer(mydict,20) 
print partial_duplicate_destroyer(mydict,200) 

#correct output: 
# {4: 9, 8: 0, 111: 43} 
# {8: 0, 111: 43} 
# {111: 43} 
+2

Nếu có một cặp khóa nằm trong khả năng chịu đựng lẫn nhau, có vấn đề gì bị xóa không? –

+0

@David Robinson - Không, nhưng trong ví dụ trên khi dung sai = 2, chỉ có một khóa trong số 1,2,3,4 nên duy trì. – fraxel

Trả lời

6

Cách tiếp cận này có thể được giảm xuống:

from itertools import combinations 

def partial_duplicate_destroyer(mydict, tolerance): 
    #Modifies in-place. Returns only as a convenience. Copy if you don't want this behaviour. 
    for key1, key2 in combinations(mydict, 2): 
     if key1 in mydict and key2 - tolerance < key1 < key2 + tolerance: 
     del mydict[key1] 
    return mydict 

Nếu chúng ta cố gắng này:

>>> mydict = {1:5,2:7,3:9,4:9,7:7,8:0,111:43,110:77} 
>>> partial_duplicate_destroyer(mydict, 2) 
{4: 9, 8: 0, 111: 43} 
>>> partial_duplicate_destroyer(mydict, 20) 
{8: 0, 111: 43} 
>>> partial_duplicate_destroyer(mydict, 200) 
{111: 43} 
>>> mydict 
{111: 43} 

này sử dụng itertools.combinations() để sản xuất tất cả các kết hợp có thể có của phím (không lặp lại). Điều này hiệu quả hơn nhiều khi bạn không bận tâm đến việc làm việc ở đâu mà bạn có các khóa giống nhau, và nó được thực hiện hiệu quả hơn trong C thay vì bên cạnh bạn với Python.

Lưu ý rằng ở đây bạn đang sửa đổi mydict tại chỗ - đó là vào cuối này, mydict{111: 43} - bạn cần phải sao chép các dict và làm việc trên nó trong chức năng, hơn là trực tiếp vào nó, nếu bạn don' t muốn hành vi này. Đây là những gì được hiển thị ở dòng cuối cùng.

+0

Thats có vẻ tuyệt vời và phiên bản đầu tiên của bạn với 'sản phẩm' cũng có vẻ ổn. – fraxel

+0

@fraxel Sản phẩm đã hoạt động, nhưng điều đó có nghĩa là bạn phải lọc ra các kết quả và kết quả lặp lại theo cách thủ công, nơi các phím đều giống nhau. Sử dụng kết hợp sẽ nhanh hơn và không đưa ra kết quả bạn không cần, giảm các kiểm tra bạn cần làm - giành chiến thắng-thắng. –

+0

Công việc tuyệt vời, cảm ơn nhiều :) – fraxel

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