2015-07-17 16 views
5

Tôi có một dict chứa danh sách và cần một cách nhanh chóng để loại trừ danh sách.Cách nhanh nhất để loại trừ danh sách trong dict

Tôi biết cách tách biệt danh sách bằng cách sử dụng hàm set(), nhưng trong trường hợp này, tôi muốn có một cách nhanh chóng lặp qua dict, deduping mỗi danh sách trên đường.

hello = {'test1':[2,3,4,2,2,5,6], 'test2':[5,5,8,4,3,3,8,9]} 

Tôi muốn nó xuất hiện như;

hello = {'test1':[2,3,4,5,6], 'test2':[5,8,4,3,9]} 

Mặc dù tôi không nhất thiết phải giữ thứ tự ban đầu của danh sách được lưu giữ.

Tôi đã cố gắng sử dụng một bộ như thế này, nhưng nó không hoàn toàn chính xác (nó không lặp lại đúng và tôi đang mất chìa khóa đầu tiên)

for key, value in hello.items(): goodbye = {key: set(value)} 
>>> goodbye 
{'test2': set([8, 9, 3, 4, 5])} 

EDIT: Sau comment PM 2Ring của dưới đây, Bây giờ tôi đang phổ biến các dict khác nhau để tránh trùng lặp ở nơi đầu tiên. Trước đây tôi đã sử dụng danh sách, nhưng việc sử dụng các bộ ngăn chặn các bản sao được thêm vào theo mặc định;

>>> my_numbers = {} 
>>> my_numbers['first'] = [1,2,2,2,6,5] 
>>> from collections import defaultdict 
>>> final_list = defaultdict(set) 
>>> for n in my_numbers['first']: final_list['test_first'].add(n) 
... 
>>> final_list['test_first'] 
set([1, 2, 5, 6]) 

Như bạn có thể thấy, đầu ra cuối cùng là bộ được xóa, theo yêu cầu.

+2

Không quan tâm trong việc giữ gìn trật tự, và cũng có danh sách của tôi là một phần của một dict. –

+2

Nếu bạn không cần phải giữ gìn trật tự, hãy đi theo một phương pháp dựa trên thiết lập: nó hiệu quả hơn các cách tiếp cận dựa trên danh sách, nhưng bạn có thể không nhận thấy sự khác biệt về tốc độ nếu danh sách của bạn nhỏ hoặc nếu chúng có ít . Và xem xét việc lưu trữ bộ chứ không phải danh sách dưới dạng giá trị của dict. OTOH, cho _very_ danh sách nhỏ, cách thiết lập có thể là _slower_. Ngoài ra, bộ sử dụng bộ nhớ nhiều hơn một chút so với danh sách. –

+0

@ PM2Ring Tôi đã đi với bộ sử dụng cuối cùng, vì vậy tránh lừa đảo ở nơi đầu tiên. defaultdict (set) và .add (n) để gắn thêm vào tập đã thực hiện thủ thuật. Đã cập nhật Q. –

Trả lời

4

Nó không lặp lại sai, bạn chỉ cần gán tạm biệt như một dict mới mỗi lần. Bạn cần gán như một dict trống, sau đó gán các giá trị cho các khóa trong mỗi lần lặp.

goodbye = {} 
for key, value in hello.items(): goodbye[key] = set(value) 
>>> goodbye 
{'test1': set([2, 3, 4, 5, 6]), 'test2': set([8, 9, 3, 4, 5])} 

Cũng kể từ bộ không giữ gìn trật tự, nếu bạn muốn giữ gìn trật tự nó là tốt nhất để thực hiện một chức năng iterating đơn giản mà sẽ trả về một danh sách mới mà bỏ qua trên các giá trị đã được thêm vào.

def uniqueList(li): 
    newList = [] 
    for x in li: 
     if x not in newList: 
      newList.append(x) 
    return newList 


goodbye = {} 
for key, value in hello.items(): goodbye[key] = uniqueList(value) 
>>> goodbye 
{'test1': [2, 3, 4, 5, 6], 'test2': [5, 8, 4, 3, 9]} 
+1

Tôi đoán đó là một trong những lý do OP cho rằng giải pháp của ông là "không hoàn toàn chính xác", và thứ tự được bảo quản trong danh sách (!) Trong đầu ra dự kiến. –

+0

OP tại đây. Trên thực tế, bảo quản trật tự không quan trọng. Vì vậy, cách tiếp cận này hoạt động tốt cho mục đích của tôi là tốt. Giải pháp của tôi không hoàn toàn chính xác vì tôi đã gán một giá trị mới thay vì phụ thêm, chỉ để lại một khóa duy nhất. –

+0

Đã thêm giải pháp bảo quản thứ tự thứ hai, vì mục đích hoàn chỉnh. – SuperBiasedMan

5

Bạn có thể sử dụng danh sách hiểu với một chức năng deduplicate riêng giữ gìn trật tự:

def deduplicate(seq): 
    seen = set() 
    seen_add = seen.add 
    return [ x for x in seq if not (x in seen or seen_add(x))] 

{key: deduplicate(value) for key, value in hello.items()} 
+0

Cũng giống như một lưu ý: việc đọc dict không hoạt động với các phiên bản Python cũ hơn như 2.7. – Daniel

+1

@Daniel nó hoạt động trong Python 2.7, nó không hoạt động trong bất kỳ phiên bản nào cũ hơn thế. –

+0

@AnandSKumar Bạn nói đúng. Tôi đã làm hỏng điều đó. – Daniel

0

Đây là một cách tiết hơn để làm việc đó, mà giữ gìn trật tự và làm việc tại tất cả các phiên bản Python:

for key in hello: 
    s = set() 
    l = [] 
    for subval in hello[key]: 
     if subval not in s: 
      l.append(subval) 
      s.add(subval) 
    hello[key] = l 
0
my_list = [1,2,2,2,3,4,5,6,7,7,7,7,7,8,9,10] 
seen = set() 
print list(filter(lambda x:x not in seen and not seen.add(x),my_list)) 
3
>>>hello = {'test1':[2,3,4,2,2,5,6], 'test2':[5,5,8,4,3,3,8,9]}  
>>>for key,value in hello.iteritems(): 
     hello[key] = list(set(value)) 
>>>hello 
{'test1': [2, 3, 4, 5, 6], 'test2': [8, 9, 3, 4, 5]} 
+1

Thật tuyệt, điều này sẽ biến 'bộ' trở lại thành một danh sách. –

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