Как сравнить несколько списков для числовой близости двух одновременно?

Скажем, у меня есть 4 списка:

A = [1.1, 1.4, 2.1, 2.4]
B = [1.3, 6.5, -1.0, 2.3]
C = [0.5, -1.0, -1.1, 2.0]
D = [1.5, 6.3, 2.2, 3.0]

Как мне 1) сравнить списки, например, A,B B,C C,D A,C и т. Д. И 2) вернуть true, если элементы +/-0,2?

Example output: (Or any other way to represent the data)
A,B [true, false, false, true]
B,C [false, false, true, false]

Мои мысли состоят в том, чтобы добавить списки в цикл for, чтобы перебрать все.

A.append(B)
A.append(C)
.
.

Но тогда я застрял, так как если я сделаю

for x in A:
    for y in A[x]:
        if A[x][y] - A[x+1][y] <= 0.2
            if A[x+1][y] - A[x][y] <= 0.2

Очевидно, это не работает. Есть ли способы перебирать списки без дубликатов и сравнивать одновременно?

заранее спасибо

3 ответа

Решение

Обновить:

Хорошо, теперь я думаю, что понимаю оба вопроса:

from itertools import combinations

A = [1.1, 1.4, 2.1, 2.4]
B = [1.3, 6.5, -1.0, 2.3]
C = [0.5, -1.0, -1.1, 2.0]
D = [1.5, 6.3, 2.2, 3.0]
lists = {'A': A, 'B': B, 'C': C, 'D': D}
tol = 0.2

def compare_lists(a, b, tol):
    return [abs(elem1-elem2) <= tol for elem1, elem2 in zip(a, b)]  # Might want '<' instead

for name1, name2 in combinations(lists.keys(), 2):
    a, b = lists[name1], lists[name2]
    print('{}, {} {}'.format(name1, name2, compare_lists(a, b, tol)))

Выход:

A, B [True, False, False, True]
A, C [False, False, False, False]
A, D [False, False, True, False]
B, C [False, False, True, False]
B, D [True, False, False, False]
C, D [False, False, False, False]

Обновление 2:

Чтобы ответить на ваш дополнительный вопрос, если списки на самом деле являются членами списка списков, вы можете сделать что-то вроде этого:

# An alternative for when the lists are nested inside another list

from itertools import combinations

lists = [
    [1.1, 1.4, 2.1, 2.4],
    [1.3, 6.5, -1.0, 2.3],
    [0.5, -1.0, -1.1, 2.0],
    [1.5, 6.3, 2.2, 3.0]
]
tol = 0.2

def compare_lists(a, b, tol):  # unchanged
    return [abs(elem1-elem2) <= tol for elem1, elem2 in zip(a, b)]  # Might want '<' instead

for i, j in combinations(range(len(lists)), 2):  # all combinations of pairs of indices
    a, b = lists[i], lists[j]
    print('{}[{}], [{}] {}'.format('lists', i, j, compare_lists(a, b, tol)))

Выход:

lists[0], [1] [True, False, False, True]
lists[0], [2] [False, False, False, False]
lists[0], [3] [False, False, True, False]
lists[1], [2] [False, False, True, False]
lists[1], [3] [True, False, False, False]
lists[2], [3] [False, False, False, False]

Ты хочешь itertools.combinations

from itertools import combinations

lists = [A, B, C, D]

for first, second in combinations(lists, 2):
    # (first, second) will be (A, B), then (A, C), then (A, D), then
    # (B, C), then (B, D), then (C, D)

Тогда вы можете сравнить с:

EPSILON = 0.2

for first, second in combinations(lists, 2):
    for a, b in zip(first, second):
        if abs(a-b) < EPSILON:
            print(True)  # or add it to a list, or etc.

Вот простой способ просто zip:

A = [1.1, 1.4, 2.1, 2.4]
B = [1.3, 6.5, -1.0, 2.3]
C = [0.5, -1.0, -1.1, 2.0]
D = [1.5, 6.3, 2.2, 3.0]

second_list = [A, B, C, D]

statements = [[round(abs(c-b), 1) == 0.2 or round(abs(c-b), 1) == 0.1
                for c, b in zip(second_list[i], second_list[i+1])]
                    for i in range(len(second_list)) if i+1 < len(second_list)]

print statements
Другие вопросы по тегам