How to compare a list in Python?

I have one list

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

I want to compare this list with another list, but also want to extract information about the contents of the list in numerical order. The whole other list has the same elements as a .

So i tried this

 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] 

I want to compare a1 with a and extract the dict values [3, 5, 6, 8] .

+5
source share
1 answer

Just go through a1 and see if there is a corresponding dictionary in the dictionary you created:

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

Demo:

 >>> 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] 

However, note that you are using floating point numbers. You may not be able to exactly match the values, since floating point numbers are binary approximations to decimal values; for example, the value 2.999999999999999 (15 nines) can be represented by the Python str() function as 3.0 , but not equal to 3.0 :

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

If your input lists a sorted, you can use the math.isclose() function (or its reverse side) along with the bisect module to maintain efficiency:

 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(ab) <= 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]) 

This checks up to two values ​​from a per input value; which is guaranteed to be equal to or lower (at index - 1 ) and the next higher value. For your sample a value 2.999999999999999 is halved by index 3 , between 2.1 and 3.0 . Since isclose(3.0, 2.999999999999999) true, it will still allow you to match this value with 4 in b .

+6
source

Source: https://habr.com/ru/post/1244579/


All Articles