2009-04-26 8 views
6

मैं वस्तुओं की एक सूची लेने का प्रयास कर रहा हूं, और उस सूची को एक निर्देश में बदल सकता हूं। श्रोताओं की सूची सूची में प्रत्येक ऑब्जेक्ट होगी, और प्रत्येक ऑब्जेक्ट में dict कुंजी एक मान मिलेगा।किसी सूची को एक सूची में बदलने का सबसे अच्छा तरीका, जहां कुंजी प्रत्येक ऑब्जेक्ट का मान है?

यहाँ कुछ का प्रतिनिधित्व क्या im कर कोड है:

class SomeClass(object): 

    def __init__(self, name): 
     self.name = name 

object_list = [ 
    SomeClass(name='a'), 
    SomeClass(name='b'), 
    SomeClass(name='c'), 
    SomeClass(name='d'), 
    SomeClass(name='e'), 
] 

object_dict = {} 
for an_object in object_list: 
    object_dict[an_object.name] = an_object 

अब जब कि कोड काम करता है, लेकिन इसकी एक सा बदसूरत, और थोड़ा धीमा। क्या कोई भी कुछ ऐसा उदाहरण दे सकता है जो तेज़/"बेहतर" हो?

संपादित करें: ठीक है, उत्तरों के लिए धन्यवाद। मुझे कहना होगा कि मैं हाथ से बने तरीके से धीमे दिखने के लिए और अधिक पाइथोनिक तरीकों को देखकर आश्चर्यचकित हूं।

संपादन 2: ठीक है, मैंने परीक्षण कोड को थोड़ा और अधिक पढ़ने योग्य बनाने के लिए अद्यतन किया है, इसलिए कई परीक्षणों के साथ।

यहां हम कोड के संदर्भ में हैं, मैं कोड में लेखकों को डालता हूं और यदि मैंने किसी को गड़बड़ कर दिया तो कृपया मुझे बताएं।

Example #1 Result: "[1.2428441047668457, 1.2431108951568604]" 
    Example #2 Result: "[3.3567759990692139, 3.3188660144805908]" 
    Example #3 Result: "[2.8346641063690186, 2.8344728946685791]" 
    Example #4 Result: "[3.0710639953613281, 3.0573830604553223]" 
    Example #5 Result: "[5.2079918384552002, 5.2170760631561279]" 
    Example #6 Result: "[3.240635871887207, 3.2402129173278809]" 
    Example #7 Result: "[3.0856869220733643, 3.0688989162445068]" 

और 50 के साथ:

Example #1 Result: "[9.8108220100402832, 9.9066231250762939]" 
    Example #2 Result: "[16.365023136138916, 16.213981151580811]" 
    Example #3 Result: "[15.77024507522583, 15.771029949188232]" 
    Example #4 Result: "[14.598290920257568, 14.591825008392334]" 
    Example #5 Result: "[20.644147872924805, 20.64064884185791]" 
    Example #6 Result: "[15.210831165313721, 15.212569952011108]" 
    Example #7 Result: "[17.317100048065186, 17.359367847442627]" 

और अंत में, 500 वस्तुओं के साथ:

Example #1 Result: "[96.682723999023438, 96.678673028945923]" 
    Example #2 Result: "[137.49416589736938, 137.48705387115479]" 
    Example #3 Result: "[136.58069896697998, 136.5823769569397]" 
    Example #4 Result: "[115.0344090461731, 115.1088011264801]" 
    Example #5 Result: "[165.08325910568237, 165.06769108772278]" 
    Example #6 Result: "[128.95187497138977, 128.96077489852905]" 
    Example #7 Result: "[155.70515990257263, 155.74126601219177]" 

from itertools import izip 
import timeit 

class SomeClass(object): 

    def __init__(self, name): 
     self.name = name 

object_list = [] 

for i in range(5): 
    object_list.append(SomeClass(name=i)) 

def example_1(): 
    'Original Code' 
    object_dict = {} 
    for an_object in object_list: 
     object_dict[an_object.name] = an_object 

def example_2(): 
    'Provided by hyperboreean' 
    d = dict(zip([o.name for o in object_list], object_list)) 

def example_3(): 
    'Provided by Jason Baker' 
    d = dict([(an_object.name, an_object) for an_object in object_list]) 

def example_4(): 
    "Added izip to hyperboreean's code, suggested by Chris Cameron" 
    d = dict(izip([o.name for o in object_list], object_list)) 

def example_5(): 
    'zip, improved by John Fouhy' 
    d = dict(zip((o.name for o in object_list), object_list)) 

def example_6(): 
    'izip, improved by John Fouhy' 
    d = dict(izip((o.name for o in object_list), object_list)) 

def example_7(): 
    'Provided by Jason Baker, removed brackets by John Fouhy' 
    d = dict((an_object.name, an_object) for an_object in object_list) 

timeits = [] 
for example_index in range(1, 8): 
    timeits.append(
     timeit.Timer(
      'example_%s()' % example_index, 
      'from __main__ import example_%s' % example_index) 
    ) 

for i in range(7): 
    timeit_object = timeits[i] 
    print 'Example #%s Result: "%s"' % (i+1, timeit_object.repeat(2)) 
सूची मैं का एक परिणाम हो रही है में 5 वस्तुओं के साथ

उत्तर देने वाले सभी के लिए धन्यवाद! मैं परिणाम से बहुत हैरान हूं। यदि किसी तेज विधि के लिए कोई अन्य युक्तियां हैं तो मुझे उन्हें सुनना अच्छा लगेगा। सबको शुक्रीया!

+0

तुम भी यहाँ सुझाव की जांच करनी चाहिए, वे बहुत समान कर रहे हैं: http://stackoverflow.com/questions/753986/is-there-a-more-pythonic-way-to-build-this-dictionary/ 754,154 # 754,154 –

उत्तर

13

अजगर 3.0 में आप एक dict समझ का उपयोग कर सकते हैं:

{an_object.name : an_object for an_object in object_list} 

यह अजगर 2 में भी संभव है, लेकिन यह थोड़ा भद्दा है:

dict([(an_object.name, an_object) for an_object in object_list]) 
+0

अरे, अच्छा, नहीं पता था कि वे (ऊपर अजगर 2.4 या में) 3.0 – hyperboreean

+3

कोई ज़रूरत नहीं में dict समझ जोड़ा एक सूची बनाने के लिए केवल इसे फेंक करने के लिए। (Object_list में आइटम के लिए (item.name, आइटम)) – bignose

+0

@bignose dict - हाँ, आप सही कर रहे हैं: इसके बजाय dict निर्माता एक सूची समझ देने के, एक जनरेटर अभिव्यक्ति है जो केवल अनुक्रम एक बार iterates का उपयोग करें। ऐसा करने के लिए जॉन फोउ का जवाब देखें। –

8
d = dict(zip([o.name for o in object_list], object_list)) 
+0

+1 अजगर 2. –

+5

+1 में यह करने के लिए एक अच्छा तरीका: इसके अलावा, आप समय और अंतरिक्ष को बचाने कर सकते हैं अगर आप izip उपयोग करते हैं, महत्वपूर्ण हो सकता है यदि सूची बहुत लंबी है। –

7

अगर आपको यह चिंता गति के साथ, फिर हम चीजों को थोड़ा सुधार सकते हैं। आपका "वर्बोज़" समाधान (जो वास्तव में ठीक है) कोई मध्यवर्ती डेटा संरचना नहीं बनाता है। दूसरी ओर, hyperboreean के समाधान, पर

d = dict(zip([o.name for o in object_list], object_list)) 

दो अनावश्यक सूचियों बनाता है: [o.name for o in object_list] एक सूची बनाता है और zip(_, _) एक और सूची बनाता है। इन दोनों सूचियों को केवल ताना के निर्माण में एक बार फिर से स्थापित किया जाता है।

हम एक जनरेटर अभिव्यक्ति के साथ सूची समझ को बदल कर एक सूची के निर्माण से बचने कर सकते हैं:

d = dict(zip((o.name for o in object_list), object_list)) 

itertools.izip साथ zip की जगह पुनरावर्तक लौट सकते हैं और दूसरी सूची बनाने से बचना होगा:

import itertools 
d = dict(itertools.izip((o.name for o in object_list), object_list)) 

हम, उसी तरह से जेसन बेकर समाधान को संशोधित कर सकता है बस वर्ग कोष्ठक हटा कर:

d = dict((an_object.name, an_object) for an_object in object_list) 
+1

यह सच है, अच्छा है। – hyperboreean

संबंधित मुद्दे

 संबंधित मुद्दे