2016-03-07 96 views
5

我有一個列表如何比較Python中的列表?

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和提取字典值[3, 5, 6, 8]

通過 a1

回答

6

只是循環,看看是否有你所創建的字典匹配鍵:

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九)例如,可以由Python str()功能3.0呈現,但不等於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.999999999999999被平分爲索引3,在2.13.0之間。由於isclose(3.0, 2.999999999999999)爲真,因此仍然會讓您將該值映射到b中的4

+0

Peters謝謝。列表中的數字是執行FORTRAN代碼的結果,用f11.5格式化。所以我認爲簡單版本就足夠了! –

+0

對,如果你有*字符串*,那麼你很好地解決了這個問題。 –