2009-02-04 20 views
112

के लिए मैं 10million के बारे में मूल्यों है कि मैं ऊपर देखो तालिका के कुछ प्रकार में डाल करने की जरूरत है, तो मैं सोच रहा था जो अधिक कुशल एक सूची या dict होगा सूची बनाम Dict?पायथन: देखो तालिका

मुझे पता है तुम दोनों के लिए कुछ इस तरह कर सकते हैं:

if something in dict_of_stuff: 
    pass 

और

if something in list_of_stuff: 
    pass 

मेरे सोचा dict तेजी से और अधिक कुशल हो जाएगा।

आपकी मदद के लिए धन्यवाद।

EDIT 1
मैं जो करने की कोशिश कर रहा हूं उस पर थोड़ा और जानकारी। Euler Problem 92। मैं यह देखने के लिए एक टेबल देख रहा हूं कि गणना की गई मान की सभी तैयार गणना की गई है या नहीं।

EDIT 2
देखने के लिए क्षमता।

संपादित 3
कोई मान मूल्य के साथ assosiated रहे हैं ... तो एक सेट बेहतर हो हैं?

+1

क्या के मामले में क्षमता? डालें? देखो? मेमोरी खपत? क्या आप मूल्य के शुद्ध अस्तित्व की जांच कर रहे हैं, या क्या इसके साथ कोई मेटाडेटा जुड़ा हुआ है? – truppo

+0

एक साइड नोट के रूप में, आपको उस विशिष्ट समस्या के लिए 10 मिलियन सूची या निर्देश की आवश्यकता नहीं है लेकिन बहुत छोटा है। – sfotiadis

+0

क्या होगा यदि तालिका सूची के बजाय एक tuple था? क्या ट्यूपल तत्वों को धोया गया है, या यह सिर्फ एक अपरिवर्तनीय सूची है? – RufusVS

उत्तर

154

स्पीड

सूचियों में लुकअप रहे हे (एन), शब्दकोशों में लुकअप परिशोधित कर रहे हैं हे (1), में आइटमों की संख्या के संबंध में डेटा संरचना। यदि आपको मूल्यों को जोड़ने की आवश्यकता नहीं है, तो सेट का उपयोग करें।दोनों

मेमोरी

शब्दकोशों और सेट hashing का उपयोग और वे केवल वस्तु भंडारण के लिए अधिक से अधिक स्मृति का उपयोग करें। एएम के मुताबिक Kuchling सुंदर कोड में, कार्यान्वयन हैश 2/3 पूर्ण रखने के लिए है, तो आप काफी कुछ स्मृति बर्बाद हो सकता है की कोशिश करता है।

आप मक्खी पर नई प्रविष्टियां (जो आप करते हैं, अपने अपडेट किए गए सवाल के आधार पर) शामिल नहीं करते हैं, यह सूची को सॉर्ट और द्विआधारी खोज का उपयोग करने के सार्थक हो सकता है। यह ओ (लॉग एन) है, और तारों के लिए धीमा होने की संभावना है, उन वस्तुओं के लिए असंभव है जिनके पास प्राकृतिक क्रम नहीं है।

+0

सूची सॉर्टिंग ओ (एन लॉग एन) – SilentGhost

+6

हां है, लेकिन यदि सामग्री कभी नहीं बदली जाती है तो यह एक ऑफ-ऑफ़ ऑपरेशन है । बाइनरी खोज ओ (लॉग एन) है। –

+0

ओटीओएच, 10 मिलियन पूर्णांक ले लेंगे, क्या, 40 मिलियन बाइट? यदि हैश 2/3 भरा है, तो यह 60 मिलियन तक चला जाता है, और वहां ओवरहेड होगा (किसी को पता है कि कितना?), लेकिन पूरी चीज कुछ सौ मेगापिक्सल मेमोरी में फिट होनी चाहिए। यह दस साल पहले एक समस्या हो सकती है, लेकिन यह वास्तव में अब नहीं है। –

6

अगर डेटा अद्वितीय सेट कर रहे हैं() सबसे कारगर होगा, लेकिन के दो - dict (जो भी विशिष्टता की आवश्यकता है, उफ़ :)

+1

वास्तव में नहीं ... डेटा भी dict के लिए अद्वितीय होना चाहिए। – nosklo

+0

मुझे एहसास हुआ है जब मैंने अपना उत्तर पोस्ट किया%% – SilentGhost

+1

@SilentGhost अगर उत्तर गलत है, तो इसे क्यों नहीं हटाया जा रहा है? अपवॉट्स के लिए बहुत बुरा है, लेकिन ऐसा होता है (ठीक है, _happened_) –

32

एक dict एक हैश तालिका है, इसलिए यह पता लगाने के लिए वास्तव में तेजी से होता है चांबियाँ। तो dict और सूची के बीच, dict तेजी से होगा। लेकिन अगर आपके पास सहयोग करने का कोई मूल्य नहीं है, तो सेट का उपयोग करना बेहतर है। यह "टेबल" भाग के बिना एक हैश टेबल है।


संपादित करें: आपके नए प्रश्न के लिए, हाँ, एक सेट बेहतर होगा। बस 2 सेट बनाएं, अनुक्रमों के लिए 1 में समाप्त होता है और अन्य अनुक्रमों के लिए 89 में समाप्त होता है। मैंने सेट का उपयोग करके इस समस्या को सफलतापूर्वक हल किया है।

5

आप एक नियम चाहते हैं।

पायथन में (अनुक्रमित) सूचियों के लिए, "इन" ऑपरेशन के लिए ओ (एन) समय की आवश्यकता होती है --- जब आपके पास बड़ी मात्रा में डेटा होता है तो अच्छा नहीं होता है। दूसरी ओर, एक हथियार एक हैश टेबल है, इसलिए आप ओ (1) लुकअप समय की उम्मीद कर सकते हैं।

जैसा कि अन्य ने नोट किया है, आप इसके बजाय एक सेट (एक विशेष प्रकार का तानाशाह) चुन सकते हैं, यदि आपके पास केवल कुंजी/मूल्य जोड़े की बजाय कुंजी हैं।

संबंधित:

  • Python wiki: अजगर कंटेनर के संचालन के समय जटिलता के बारे में जानकारी।
  • SO: अजगर कंटेनर आपरेशन समय और स्मृति जटिलताओं
+1

क्रमबद्ध सूचियों के लिए भी, "इन" ओ (एन) है। –

+1

किसी लिंक किए गए सूची के लिए, हाँ --- लेकिन "सूची" पायथन में ज्यादातर लोगों वैक्टर, जब हल कर जो हे (1) और ओ में एक खोज आपरेशन (लॉग एन), में अनुक्रमित पहुँच प्रदान करते हैं क्या कहेंगे हैं। – zweiterlinde

+0

क्या आप कह रहे हैं कि एक सॉर्टेड सूची पर लागू 'इन' ऑपरेटर एक अनारक्षित एक (यादृच्छिक मूल्य की खोज के लिए) पर लागू होने से बेहतर प्रदर्शन करता है?(मुझे नहीं लगता कि वे आंतरिक रूप से वैक्टर के रूप में कार्यान्वित किए गए हैं या किसी लिंक किए गए सूची में नोड्स प्रासंगिक हैं।) – martineau

0

आप वास्तव में तालिका में 10 लाख मान संग्रहीत की जरूरत नहीं है, तो यह एक बड़ी बात है किसी भी तरह से नहीं है।

सुझाव: कितना बड़ा अपने परिणाम वर्गों संचालन के पहले योग के बाद हो सकता है के बारे में सोचते हैं। सबसे बड़ा संभव परिणाम 10 लाख तुलना में काफी छोटा हो जाएगा ...

24

set() है आप क्या चाहते हैं। ओ (1) लुकअप, और एक dict से छोटे।

21

मैं कुछ बेंच मार्किंग किया था और यह पता चला है कि dict दोनों सूची की तुलना में तेजी और बड़े डेटा सेट के लिए सेट किया गया है, लिनक्स पर एक i7 CPU पर अजगर 2.7.3 चल:

  • python -mtimeit -s 'd=range(10**7)' '5*10**6 in d'

    10 छोरों, 3 का सबसे अच्छा: पाश प्रति 64.2 msec

  • python -mtimeit -s 'd=dict.fromkeys(range(10**7))' '5*10**6 in d'

    10000000 छोरों, 3 का सबसे अच्छा: 0.075 पाश प्रति 9 usec

  • python -mtimeit -s 'from sets import Set; d=Set(range(10**7))' '5*10**6 in d'

    1000000 छोरों, 3 का सबसे अच्छा: पाश

आप देख सकते हैं प्रति 0.262 usec, dict काफी और के बारे में 3 बार सूची की तुलना में तेजी सेट की तुलना में तेजी से होता है । कुछ अनुप्रयोगों में आप अभी भी इसकी सुंदरता के लिए सेट चुनना चाहते हैं, हालांकि। और यदि डेटा सेट वास्तव में छोटे हैं (< 1000 तत्व) सूचियां बहुत अच्छी तरह से प्रदर्शन करती हैं।

+0

यह बिल्कुल विपरीत नहीं होना चाहिए? सूची: 10 * 64.2 * 1000 = 642000 usec, dict: 10000000 * 0.0759 = 759000 usec और set: 1000000 * 0.262 = 262000 usec ... तो सेट सबसे तेज़ हैं, सूची के बाद और आपके उदाहरण पर आखिरी बार के साथ। या क्या मैं कुछ न कुछ भूल रहा हूं? – andzep

+0

... लेकिन मेरे लिए यहां सवाल यह है कि: इस बार वास्तव में क्या माप रहे हैं? किसी दिए गए सूची, निर्देश या सेट के लिए एक्सेस समय नहीं है, लेकिन अधिक, समय और लूप सूची, dict, सेट और अंत में एक मान को खोजने और एक्सेस करने के लिए। तो, क्या इस सवाल को बिल्कुल करना है? ... हालांकि यह दिलचस्प है ... – andzep

+5

@andzep, आप गलत हैं, '-s' विकल्प 'टाइमिट' वातावरण स्थापित करना है, यानी यह कुल समय में गिना नहीं जाता है। '-s' विकल्प केवल एक बार चलाया जाता है। पायथन 3.3 पर, मुझे ये परिणाम मिलते हैं: जीन (रेंज) -> 0.229 यूकेसी, सूची -> 157 एमसीसी, dict -> 0.0806 usec, set -> 0.0807 usec। सेट और dict प्रदर्शन समान है। हालांकि डिक्टेंट को निर्धारित करने के लिए धन्यवाद (कुल समय 13.580 बनाम 11.803 एस) – sleblanc

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