2009-11-04 17 views
10

सूचियाँ मैं दो बहुत बड़ी सूचियों और पाश के माध्यम से यह एक बार में कम से कम एक दूसरे लेता है और मैं इसे 200,000 बार करने की ज़रूरत है। एक बनाने के लिए दो सूचियों में डुप्लिकेट को हटाने का सबसे तेज़ तरीका क्या है?सबसे तेजी से रास्ता डुप्लिकेट में निकालने के लिए अजगर

import itertools 
output_list = list(set(itertools.chain(first_list, second_list))) 

थोड़ा सा अद्यतन:

+0

आपका समय संकेत मिलता है कि एक पाश वर्तमान में 55 घंटे लगते हैं। यह सुनना दिलचस्प होगा कि प्रस्तावित समाधान कब तक लेते हैं। – behindthefall

उत्तर

20

यह सबसे तेज़ तरीका मैं के बारे में सोच सकता है jcd बताते हैं के रूप में, आपके आवेदन पर निर्भर करता है, तो आप शायद परिणाम एक सूची वापस करने के लिए परिवर्तित करने के लिए की जरूरत नहीं है। के बाद से एक सेट से ही iterable है, तो आप सिर्फ यह सीधे उपयोग करने में सक्षम हो सकता है:

output_set = set(itertools.chain(first_list, second_list)) 
for item in output_set: 
    # do something 

कि हालांकि खबरदार किसी भी समाधान set() के उपयोग शायद अपनी सूची में तत्वों को पुन: व्यवस्थित होगा शामिल है, तो कोई गारंटी नहीं है कि तत्वों है किसी भी विशेष क्रम में होगा। उस ने कहा, चूंकि आप दो सूचियों का संयोजन कर रहे हैं, इसलिए एक अच्छे कारण के साथ आना मुश्किल है कि आपको किसी भी तरह के विशेष आदेश की आवश्यकता क्यों होगी, इसलिए शायद ऐसा कुछ नहीं है जिसके बारे में आपको चिंता करने की ज़रूरत है।

+0

ओह, आपका समाधान मेरा से बेहतर है :) – shylent

+0

सभी के उत्तरों के लिए धन्यवाद, उन्होंने सभी को बहुत मदद की है! :) – Cookies

+1

+1। यदि आदेश * * महत्वपूर्ण है, तो शायद एक आदेश दिया सेट करना होगा: http://stackoverflow.com/questions/1653970/does-python-have-an-ordered-set – Stephan202

3
result = list(set(list1).union(set(list2))) 

इस तरह मैं इसे करूँगा। मैं प्रदर्शन के बारे में इतना निश्चित नहीं हूं, लेकिन यह हाथ से ऐसा करने से निश्चित रूप से बेहतर है।

+0

'set.union (स्वयं, अन्य)' के रूप में समझा कि मेरी कोड कर रहा था के लिए 'other' – u0b34a0f6ae

7

डैनियल में कहा गया है के रूप में, एक सेट डुप्लिकेट प्रविष्टियों को शामिल नहीं कर सकते हैं - तो जोड़ सूचियां:

set(list1 + list2) 

फिर वापस एक सूची के लिए:

list1 + list2 

फिर नई सूची एक सेट में बदलने का

list(set(list1 + list2)) 
+2

धन्यवाद किसी भी iterable साथ ठीक है। मुझे इससे हराएं! :-) मैं बस उल्लेख करता हूं कि मैंने सूचियों को संयोजित करने के बजाय 'itertools.chain()' का उपयोग करने के लिए अपना उत्तर संपादित किया है क्योंकि यह स्मृति में तीसरी बड़ी सूची आवंटित करने से बचाता है। 'सेट()' कन्स्ट्रक्टर को वास्तव में एक सूची की आवश्यकता नहीं होती है, इसे केवल एक पुनरावर्तनीय की आवश्यकता होती है जो सभी तत्वों पर पुन: सक्रिय हो सकती है, और 'itertools.chain()' अधिक कुशलता से (प्रतिलिपि से बचकर) करता है। –

11

मैं इस तरह कुछ सुझाऊंगा:

def combine_lists(list1, list2): 
    s = set(list1) 
    s.update(list2) 
    return list(s) 

यह पहले दो के संयोजन के एक राक्षस सूची बनाने के समस्या का निराकरण किया।

क्या आप उत्पादन के साथ कर रहे हैं पर निर्भर करता है, एक सूची वापस करने के लिए परिवर्तित करने के लिए परेशान नहीं है। अगर ऑर्डरिंग महत्वपूर्ण है, तो आपको इसके आसपास शेन्ज़िगन्स को सजाने/सॉर्ट/अनदेखा करने की आवश्यकता हो सकती है।

+2

सहमत हैं, दो सूचियों को संयोजित करने की कोई आवश्यकता नहीं है - जो बस स्मृति को बर्बाद कर देती है। मैं उपरोक्त उपयोग किए गए इटरेटर दृष्टिकोण बनाम 's.update (list2) 'कॉल करने के बीच प्रदर्शन अंतर देखने में रूचि रखूंगा। आपका दृष्टिकोण थोड़ा तेज हो सकता है। हालांकि, जैसा कि आप इंगित करते हैं, आपको अंत में एक सूची में वापस परिवर्तित नहीं करके बहुत बड़ी प्रदर्शन बचत मिलती है। –

+1

मैंने कुछ समय व्यतीत किया, और ऐसा लगता है कि यह तेज़ है, लेकिन कभी भी 5% या 10% से एक या दूसरे तरीके से नहीं। मैं इसे एक ड्रॉ कहूंगा। – jcdyer

+0

यह देखते हुए कि itertools केवल दो ऑब्जेक्ट्स चेन कर रहा है, मैं कहूंगा कि इसका प्रभाव बहुत कम है, इसलिए सवाल यह है कि सेट() के बीच एक बड़ी सूची में महत्वपूर्ण अंतर है, या सूची (।) में आधा सेट()) बाकी के बाकी हिस्सों में। ऐसा लगता है कि ऐसा नहीं है। – jcdyer

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