2013-05-04 20 views
5

Sözlüğe bir liste dönüştürmek için: Şu andaVerimli yolu bir sözlüğüne aşağıdaki listeyi dönüştürmek için en verimli şekilde ihtiyaç

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

, ben aşağıdakileri yapın:

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

Ancak, aynı şeyi elde etmenin daha etkili bir yolu olması gerektiğine inanıyorum. Herhangi bir fikir ? Bir jeneratör ifadesiyle

+4

Ben bundan daha verimli bir şey olmadığına inanıyorum. "Daha az satırın" "hızlı" ile aynı olmadığını unutmayın. Her şey dilin bu çizgileri nasıl genişlettiğine bağlı. – LtWorf

+0

Karşılaştırma yanıt güncellendi, kısa (4 öğe), uzun (13312 öğeler) ve çok uzun (27262976 öğe) listelerle ilgili cevapları karşılaştırır. – FallenAngel

cevap

12

kullanım dict():

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

Zamanlama sonuçları 10 ** 6 öğeler için:

>>> 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 
(@PaoloMoretti önerdiği gibi) dict anlama kullanma

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

so.py:

Bunun yürütme zaman bunları karşılaştırmak daha iyi olduğunu tahmin
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 (": ") x lis için bir jeneratör ifadesidir, liste kavraması değildir. Dolayısıyla, geçici bir veri yapısı tahsis etmiyor – Kos

+0

Evet hatayım, üzgünüm. Her neyse daha verimli değil. Aynısı. – LtWorf

+1

@LtWorf bunu okudu: http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Loops LC'ler ve jeneratör ifadeleri eşdeğer 'for' döngü sürümünden daha hızlıdır. –

0

... 100.000 döngüler ve her döngü için 3 test için test edilmiştir

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 

. Gördüğünüz gibi, en hızlı yürütme süresi case1()'a ait: standart for loop.

Sonuç: 1 liner yöntemleri daha hızlı olduklarını göstermez, aslında temel for döngü genellikle gitmek için en hızlı yoldur.

Güncelleme: sonuçları için 13312 ürün, temel liste 26 öğeyi, kalanı bu listenin kopyalarını listele vb. 26 ürün var, gerisi bu öğelerin kopyalarıdır Son test 27262976 toplam öğe listesi ile gerçekleşir temel listesi: Zamanlama her döngü

%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 

Güncelleme 2 için 3 iyi 1000 döngüler üzerinden hesaplanan ve Bu liste. Zamanlama, her döngü için 10 döngüden ve en iyi 3'ten hesaplanır (çok uzun bir listenin yürütülmesi büyük zaman alır).

%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

Ancak neredeyse tüm uygulamalar için, yaptığınız işi daha da açık hale getirdiğinden, 2. vakaları tercih ediyorum. – poke

+0

Daha büyük bir veri kümesi için bazı sonuçlarınız var mı? – inf

+0

@poke belki, ama burada soru _efficiency_, okunabilir değil. – FallenAngel

1
>>> dict(map(lambda s: s.split(":"), ["A:1", "B:2", "C:3", "D:4"])) 
{'A': '1', 'C': '3', 'B': '2', 'D': '4'} 
İlgili konular