2013-05-04 27 views
5

tôi cần sự giúp đỡ một cách hiệu quả nhất để chuyển đổi danh sách sau đây vào một cuốn từ điển:cách hiệu quả để chuyển đổi một danh sách vào từ điển

l = ['A:1','B:2','C:3','D:4'] 

Hiện nay, tôi thực hiện như sau:

mydict = {} 
for e in l: 
    k,v = e.split(':') 
    mydict[k] = v 

Tuy nhiên, tôi tin rằng cần có một cách hiệu quả hơn để đạt được điều tương tự. Bất kỳ ý tưởng ?

+4

Tôi tin rằng không có gì hiệu quả hơn thế. Hãy nhớ rằng "ít dòng" hơn không giống với "nhanh hơn". Tất cả đều tóm tắt cách ngôn ngữ mở rộng các dòng đó. – LtWorf

+0

Câu trả lời so sánh của tôi được cập nhật, so sánh các câu trả lời có liên quan cho các danh sách ngắn (4 mục), dài (13312 mục) và danh sách dài (27262976 mục). – FallenAngel

Trả lời

12

sử dụng dict() với một biểu thức máy phát điện:

>>> lis=['A:1','B:2','C:3','D:4'] 
>>> dict(x.split(":") for x in lis) 
{'A': '1', 'C': '3', 'B': '2', 'D': '4'} 

Sử dụng dict-hiểu (theo đề nghị của @PaoloMoretti):

>>> {k:v for k,v in (e.split(':') for e in lis)} 
{'A': '1', 'C': '3', 'B': '2', 'D': '4'} 

kết quả Timing cho 10 ** 6 hạng mục:

>>> from so import * 
>>> %timeit case1() 
1 loops, best of 3: 2.09 s per loop 
>>> %timeit case2() 
1 loops, best of 3: 2.03 s per loop 
>>> %timeit case3() 
1 loops, best of 3: 2.17 s per loop 
>>> %timeit case4() 
1 loops, best of 3: 2.39 s per loop 
>>> %timeit case5() 
1 loops, best of 3: 2.82 s per loop 

so.py:

a = ["{0}:{0}".format(i**2) for i in xrange(10**6)] 

def case1(): 
    dc = {} 
    for i in a: 
     q, w = i.split(':') 
     dc[q]=w 

def case2(): 
    dict(x.split(":") for x in a) 


def case3(): 
    {k:v for k,v in (e.split(':') for e in a)} 

def case4(): 
    dict([x.split(":") for x in a]) 

def case5(): 
    {x.split(":")[0] : x.split(":")[1] for x in a} 
+0

@LtWorf 'x.split (": ") cho x trong lis' là một biểu thức máy phát điện, không phải là một danh sách hiểu. Do đó nó không phân bổ một cấu trúc dữ liệu temprary – Kos

+0

Có lỗi của tôi, xin lỗi. Dù sao nó không hiệu quả hơn. Nó giống nhau. – LtWorf

+1

@LtWorf đọc: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Loops Biểu thức của LC và trình tạo tốc độ nhanh hơn phiên bản vòng lặp 'for' tương đương. –

0

Tôi đoán nó là tốt hơn để so sánh chúng bằng thời gian thực hiện ...

a = ['A:1','B:2','C:3','D:4'] 

def case1(): 
    dc = {} 
    for i in a: 
     q, w = i.split(':') 
     dc[q]=w 

def case2(): 
    dict(x.split(":") for x in a) 


def case3(): 
    {x.split(":")[0] : x.split(":")[1] for x in a} 


%timeit -n 100000 case1() 
>> 100000 loops, best of 3: 1.95 us per loop 


%timeit -n 100000 case2() 
>> 100000 loops, best of 3: 3.05 us per loop 


%timeit -n 100000 case3() 
>> 100000 loops, best of 3: 3.39 us per loop 

Tested cho 100.000 vòng và 3 kiểm tra cho mỗi vòng lặp. Như bạn có thể thấy, thời gian thực hiện nhanh nhất thuộc về case1(): tiêu chuẩn for loop.

Kết quả: 1 phương pháp lót không có nghĩa là chúng nhanh hơn, trên thực tế, vòng lặp cơ bản for thường là cách nhanh nhất để đi.

Cập nhật: kết quả cho danh sách 13312 mục, danh sách cơ bản có 26 mục, còn lại là bản sao của các mục đó trong danh sách. Thời gian được tính trên 1000 vòng và tốt nhất của 3 cho mỗi vòng lặp

%timeit -n 1000 case3() 
1000 loops, best of 3: 9.49 ms per loop 

%timeit -n 1000 case2() 
1000 loops, best of 3: 5.79 ms per loop 

%timeit -n 1000 case1() 
1000 loops, best of 3: 5.55 ms per loop 

Cập nhật 2: thử nghiệm cuối cùng diễn ra với một danh sách tổng 27262976 mục, danh sách cơ bản có 26 mặt hàng, còn lại là các bản sao của những mặt hàng wtihin danh sách. Thời gian được tính toán trên 10 vòng lặp và tốt nhất là 3 cho mỗi vòng lặp (vì việc thực hiện danh sách rất dài mất nhiều thời gian).

%timeit -n 10 case1() 
10 loops, best of 3: 11.4 s per loop 

%timeit -n 10 case2() 
10 loops, best of 3: 12.1 s per loop 

%timeit -n 10 case3() 
10 loops, best of 3: 20.2 s per loop 
+0

Nhưng đối với gần như tất cả các ứng dụng, tôi vẫn thích trường hợp 2 vì nó chỉ rõ ràng hơn những gì bạn đang làm. – poke

+0

Bạn cũng có một số kết quả cho tập dữ liệu lớn hơn không? – inf

+0

@poke có thể, nhưng câu hỏi ở đây là _efficiency_, không thể đọc được. – FallenAngel

1
>>> dict(map(lambda s: s.split(":"), ["A:1", "B:2", "C:3", "D:4"])) 
{'A': '1', 'C': '3', 'B': '2', 'D': '4'} 
Các vấn đề liên quan