2016-03-07 14 views
5

मैं एक सूची हैपायथन में सूची की तुलना कैसे करें?

a = [1.0, 2.0, 2.1, 3.0, 3.1, 4.2, 5.1, 7.2, 9.2] 

मैं अन्य सूची के साथ इस सूची में तुलना करना चाहते हैं, लेकिन यह भी मैं सांख्यिक order.All अन्य सूची में सूची सामग्री के बारे में जानकारी निकालने के लिए चाहते हैं तत्वों कि a के रूप में ही हैं।

तो मैं इस

a = [1.0, 2.0, 2.1, 3.0, 3.1, 4.2, 5.1, 7.2, 9.2] 
b = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
print dict(zip(a,b)) 

a1=[2.1, 3.1, 4.2, 7.2] 

मैं एक साथ a1 तुलना और dict निकालना चाहते महत्व देता [3, 5, 6, 8] कोशिश की है।

उत्तर

6

बस a1 के माध्यम से लूप और अगर वहाँ शब्दकोश आपके द्वारा बनाए में मिलान कुंजी है देखें:

mapping = dict(zip(a, b)) 
matches = [mapping[value] for value in a1 if value in mapping] 

डेमो:

>>> a = [1.0, 2.0, 2.1, 3.0, 3.1, 4.2, 5.1, 7.2, 9.2] 
>>> b = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> a1 = [2.1, 3.1, 4.2, 7.2] 
>>> mapping = dict(zip(a, b)) 
>>> [mapping[value] for value in a1 if value in mapping] 
[3, 5, 6, 8] 

हालांकि, ध्यान में रखना है कि आप चल बिन्दु का उपयोग कर रहे संख्याएं। हो सकता है कि आप मानों को बिल्कुल मिलान नहीं कर पाएंगे, क्योंकि फ़्लोटिंग पॉइंट नंबर दशमलव मानों के लिए बाइनरी अनुमान हैं; मूल्य 2.999999999999999 (15 नौ) उदाहरण के लिए, 3.0 के रूप में अजगर str() समारोह द्वारा प्रस्तुत किया जा सकता है, लेकिन बराबर नहीं3.0 के लिए है:

>>> 2.999999999999999 
2.999999999999999 
>>> str(2.999999999999999) 
'3.0' 
>>> 2.999999999999999 == 3.0 
False 
>>> 2.999999999999999 in mapping 
False 

अपने इनपुट सूची में शामिल a क्रमबद्ध हो जाता है, तो आप math.isclose() function इस्तेमाल कर सकते हैं (या इसे का बैकपोर्ट), एक साथ bisect module साथ कुशल मिलान रखने के लिए:

import bisect 
try: 
    from math import isclose 
except ImportError: 
    def isclose(a, b, rel_tol=1e-09, abs_tol=0.0): 
     # simplified backport, doesn't handle NaN or infinity. 
     if a == b: return True 
     return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol) 

result = [] 
for value in a1: 
    index = bisect.bisect(a, value) 
    if index and isclose(a[index - 1], value): 
     result.append(b[index - 1]) 
    elif index < len(a) and isclose(a[index], value): 
     result.append(b[index]) 

यह a इनपुट मूल्य प्रति से दो मानों अप करने के लिए परीक्षण; एक जो बराबर या कम (index - 1 पर) और अगले, उच्च मूल्य की गारंटी है। आपके नमूने a के लिए, मूल्य 2.9999999999999993 पर 2.1 और 3.0 के बीच विभाजित किया गया है। चूंकि isclose(3.0, 2.999999999999999) सत्य है, फिर भी यह आपको में 4 पर उस मान को मैप करने देगा।

+0

पीटर्स धन्यवाद। सूची में संख्याएं फोरट्रान कोड के निष्पादन के परिणामस्वरूप हैं, जो f11.5 के साथ बनाई गई है। इसलिए मुझे लगता है कि सरल संस्करण पर्याप्त होगा! –

+0

ठीक है, अगर आपके पास * स्ट्रिंग्स * है, तो आप इस मुद्दे को काफी अच्छी तरह से स्कर्ट करते हैं। –

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