2013-07-20 8 views
8

मैं कुछ हफ्तों के लिए इस पर काम कर रहा हूं और मैंने पाइथन मेमोरी रिसाव के बारे में कई प्रश्न पढ़े हैं, लेकिन मैं इसे समझ नहीं पा रहा हूं।पायथन को मार दिया जाता है (शायद स्मृति रिसाव)

मेरे पास एक फ़ाइल है जिसमें लगभग 7 मिलियन लाइनें हैं। प्रत्येक पंक्ति के लिए, मुझे एक शब्दकोश बनाना होगा।

[{'a': 2, 'b':1}{'a':1, 'b':2, 'c':1}] 

क्या मैं कर रहा हूँ है ...

list = [] 
for line in file.readlines(): 
    terms = line.split(" ") 
    dict = {} 
    for term in terms: 
     if term in dict: 
      dict[term] = dict[term] + 1 
     else: 
      dict[term] = 1 
    list.append(dict.copy()) 
    dict.clear() 
file.close() 

समस्या यह हमेशा 6000000 रेखा के आसपास की हत्या कर दी हो जाता है जब मैं इस चलने वाले है: तो इस शब्दकोश की एक सूची है कि लग रहा है की तरह है। मूल रूप से मैं बस dict = {} कर रहा था लेकिन इसे बदल दिया, इसलिए मैं इसी तरह की पोस्ट पढ़ने के बाद dict.clear() करता हूं, लेकिन इसमें कुछ भी सुधार नहीं हुआ। मुझे परिपत्र संदर्भों के बारे में कुछ पदों के बारे में बताया गया है और मैंने अपने कोड में देखा लेकिन मुझे नहीं लगता कि मुझे वह समस्या है।

मुझे संदेह है कि सूची में 7 मिलियन शब्दकोशों को संग्रहीत करने के लिए पायथन में नहीं रखा जा सकता है? मैं किसी भी सलाह की सराहना करता हूं कि मैं पूरी चीजों को मारने के बिना कैसे चला सकता हूं।

+2

आप यहां क्या हासिल करने की कोशिश कर रहे हैं? –

+0

@ThomasOrozco मैं थोड़ा मेरे सवाल संपादित, लेकिन मैं क्या करने की कोशिश कर रहा हूँ प्रत्येक पंक्ति – kabichan

+2

आप file.readlines में _for लाइन की जगह() की कोशिश क्या के लिए अवधि गिनती शब्दकोश स्टोर करने के लिए है: फ़ाइल में _ _for लाइन द्वारा: _ ? – uselpa

उत्तर

8

कोशिश (संस्करण 2.7.4 है):

from collections import Counter 
with open('input') as fin: 
    term_counts = [Counter(line.split()) for line in fin] 

मेरा मानना ​​है कि यह है कि तुम क्या अपने कोड के साथ प्राप्त करने की कोशिश कर रहे हैं।

यह .readlines() स्मृति पहले में फ़ाइल लोड करने से बचा जाता है, Counter का इस्तेमाल करता है गिनती करने के लिए और एक ही बार में चारों ओर faffing रिक्त/आवंटित// समाशोधन शब्दकोशों सूची में जोड़कर बिना सूची बनाता है ...

+0

मैंने कोशिश की और यह अभी भी मारे गए .. केवल एक चीज जो मैंने आपके से अलग की है वह यह है कि मेरे पास फ़ाइल नाम के लिए एक चर है, इसलिए मैंने खुले (फ़ाइल नाम) को फिन के रूप में किया: 'और बाकी वही है। – kabichan

+0

@ kabichan यह उतना आसान है जितना आप चाहते हैं - ऐसा लगता है जैसे आपको डिस्क पर डेटा को डीबी –

+0

में स्टोर करना पड़ सकता है यदि ऐसा इसलिए नहीं है क्योंकि मैं ऐसा नहीं कर रहा हूं जो मैं कर सकता हूं, तो मैं आगे बढ़ सकता हूं और कुछ और कोशिश करो। मैं आपका जवाब उत्तर के रूप में स्वीकार करूंगा क्योंकि ऐसा लगता है कि यह समान समस्याओं को हल करेगा। आपकी सलाह के लिए बहुत - बहुत धन्यवाद। – kabichan

1

नहीं है कोड के एक स्निपेट के साथ मेमोरी रिसाव नहीं हो सकता है, क्योंकि पाइथन कम से कम आधा रास्ता सभ्य कचरा संग्रह का उपयोग करता है। एक संभावित मुद्दा यह है कि आप स्मृति से बाहर हो रहे हैं (इसलिए निश्चित रूप से स्टार्टर्स के लिए .readlines से बचें; इसके बजाय "my_file में लाइन के लिए" का उपयोग करें); एक शब्दकोष वास्तव में विभिन्न कारणों से स्मृति का काफी उपयोग करता है - एक यह है कि एक शब्दकोश जानबूझकर हैश टेबल का उपयोग करता है जो कि आपके वास्तविक वर्तमान सेट की तुलना में काफी बड़ा होता है, दोनों टकराव को कम करने में मदद करने के लिए, लेकिन जल्दी से बहुत कुछ जोड़ने में सक्षम होने के लिए यदि आवश्यक हो तो नई कुंजी की, प्रति प्रविष्टि एम (1) समय के साथ। चूंकि आप मरने से पहले अपनी फ़ाइल के अंत तक बहुत करीब आ रहे हैं, एक चीज जिसे आप कोशिश कर सकते हैं, अपने अंतिम निर्देश को के-टुपल्स के 2-टुपल के रूप में संग्रहीत कर रहा है, जहां पहले के-टुपल में के कुंजी हैं जिन्हें आप स्टोर करना चाहते हैं , और दूसरा के-टुपल आपके के के लिए कुंजी है। इस कीमत पर, कुछ स्मृति को बचाने चाहिए कि अपना कोई 2-tuples टी में से एक में my_key की लुक-अप करने के लिए आप की तरह कुछ करने की आवश्यकता होगी: एक नज़र के लिए

match_idx = [i for i in xrange(len(T[0])) if T[0][i] == my_key] 
if len(match_idx) == 0: 
    # no match, do whatever 
else: #match 
    count = T[1][match_idx[0]] 
    # now do whatever with count 

चलने का समय अप निरंतर समय के बजाय खोज की जाने वाली कुंजियों की संख्या में रैखिक होगा (हालांकि ध्यान दें कि एक शब्दकोश लुकअप करने के लिए हैशिंग एक मामूली ऑपरेशन नहीं है, इसलिए स्थिर ऑपरेशन के लिए स्थिर स्थिर से बड़ा है)। यदि आपने अपनी चाबियाँ क्रमबद्ध क्रम में संग्रहीत की हैं तो आप अपनी कुंजी को तुरंत ढूंढने के लिए बाइनरी खोज का उपयोग कर सकते हैं लेकिन इसके लिए अधिक कोड की आवश्यकता होगी, और मुझे लगता है कि आप भाग में पायथन का उपयोग कर रहे हैं क्योंकि यह संक्षिप्त कोड देता है। हालांकि यदि आप पहले से ही अपने 6 मिलियन शब्दकोशों को सफलतापूर्वक बना रहे हैं, तो औसतन आपके 7 मिलियन शब्दकोशों में उनमें कई कुंजी नहीं होनी चाहिए। इसलिए यदि आप वास्तव में अपने डेटा सेट के लिए पायथन का उपयोग करना चाहते हैं, तो यह तब तक जाने का एकमात्र तरीका हो सकता है जब तक कि आपको अधिक मेमोरी वाली मशीन न मिल जाए।

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