如何一次比较多个列表的数值接近度?
How to compare multiple lists for numerical closeness two at a time?
假设我有 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)return 如果元素为 +/-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
显然是行不通的。
有没有办法在不重复的情况下遍历列表并同时进行比较?
提前致谢
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.
更新:
好的,现在我想我明白你问的两个问题了:
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]
更新二:
要回答你的后续问题,如果列表实际上是列表列表的成员,你可以类似地做这样的事情:
# 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]
这里有一个简单的方法 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
假设我有 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)return 如果元素为 +/-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
显然是行不通的。 有没有办法在不重复的情况下遍历列表并同时进行比较?
提前致谢
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.
更新:
好的,现在我想我明白你问的两个问题了:
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]
更新二:
要回答你的后续问题,如果列表实际上是列表列表的成员,你可以类似地做这样的事情:
# 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]
这里有一个简单的方法 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