2016-03-07 10 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 с и извлечь 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 девяток), например, могут быть представлены с помощью функции 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.1 и 3.0. Поскольку isclose(3.0, 2.999999999999999) истинно, это все равно позволит вам сопоставить это значение с 4 в b.

+0

Peters Спасибо. Цифры в списке являются результатом выполнения кода FORTRAN, сформированного с помощью f11.5. Так что я думаю, что простой версии будет достаточно! –

+0

Правильно, если у вас есть * строки *, то вы хорошо обходите вокруг вопроса. –