我有3个列表的列表,每个列表中每个列表都有1个列表。
data_set = [
['AB12345',['T','T','C','C','A','C','A','G','C','T','T','T','T','C']],
['AB12346',['T','T','C','C','A','C','C','G','C','T','C','T','T','C']],
['AB12347',['T','G','C','C','A','C','G','G','C','T','T','C','T','C']]
]
我有一个compare方法,它将为我提供包含字符而不是ID的列表的相似性。
def compare(_from, _to):
similarity = 0
length = len(_from)
if len(_from) != len(_to):
raise Exception("Cannot be compared due to different length.")
for i in range(length):
if _from[i] == _to[i]:
similarity += 1
return similarity / length * 100
compare(data_set[0][1], data_set[1][1])
通过使用compare方法,我使用了for循环将“ a”列表与其他列表进行比较,如“ a”比较“ a”,“ a”比较“ b”和“ a”比较“C”。
for i in range(len(data_set)):
data_set[i].append(compare(data_set[0][1], data_set[i][1]))
print(round(data_set[i][2], 2), end=", ")
但是在将第一个列表与其他列表及其自身进行比较之后,我如何循环到第二个列表和第三个列表,并再次与其他列表进行比较以获得相似性?就像,((“ b”与“ a”比较,“ b”与“ b”比较,“ b”与“ c”比较)和(“ c”与“ a”比较,“ c”与“ b”比较, “ c”与“ c”相比)。
答案 0 :(得分:1)
只需使用第二个嵌套循环
for i in range(len(data_set)):
for j in range(len(data_set)):
data_set[i].append(compare(data_set[j][1], data_set[i][1]))
print(round(data_set[i][2], 2), end=", ")
答案 1 :(得分:1)
为便于将来参考,最好在代码中包含输入列表(a,b,c),而不要使用屏幕快照来节省人们必须键入整个列表的时间。我使用了一些较短的版本进行测试。
您可以执行以下操作来遍历两个列表并比较结果。这比使用for i in range(len(data_set)):
# Make some test data
a= ["ID_A", ['T', 'G', 'A']]
b= ["ID_B", ['T', 'C', 'A']]
c= ["ID_C", ['C', 'A', 'A']]
data = [a,b,c]
# entry1 takes each of the values a,b,c in order, and entry2 will do the same,
# so you'll have all possible combinations.
for entry1 in data:
for entry2 in data:
score = compare(entry1[1], entry2[1])
print("Compare ", entry1[0], " to ", entry2[0], "Score :", round(score))
输出:
Compare ID_A to ID_A Score : 100
Compare ID_A to ID_B Score : 67
Compare ID_A to ID_C Score : 33
Compare ID_B to ID_A Score : 67
Compare ID_B to ID_B Score : 100
Compare ID_B to ID_C Score : 33
Compare ID_C to ID_A Score : 33
Compare ID_C to ID_B Score : 33
Compare ID_C to ID_C Score : 100
与将分数保存在列表中相比,最好将分数存储在不同的数组中。
答案 2 :(得分:0)
您还可以使用itertools.combinations
比较所有子列表。另外,在您的compare()
函数中,您可能需要考虑返回一个表明子列表不具有可比性的值,而不是引发异常,以便在比较较大的子列表集时不会过早地短路循环。>
以下是一个示例(还包括您的compare()
函数的一个稍微简化的版本,当由于长度原因而导致列表不可比较时,该函数将返回-1
,但由于该列表不与自身进行比较,因此在这种情况下,返回值将始终为100,这似乎是对性能的浪费。
import itertools
data_set = [
['AB12345',['T','T','C','C','A','C','A','G','C','T','T','T','T','C']],
['AB12346',['T','T','C','C','A','C','C','G','C','T','C','T','T','C']],
['AB12347',['T','G','C','C','A','C','G','G','C','T','T','C','T','C']]
]
def compare(a, b):
length = len(a) if len(a) == len(b) else 0
similarity = sum(1 for i in range(length) if a[i] == b[i])
return similarity / length * 100 if length else -1
for a, b in itertools.combinations(data_set, 2):
compared = a[0] + ' and ' + b[0]
result = compare(a[1], b[1])
print(f'{compared}: {result}')
# OUTPUT
# AB12345 and AB12346: 85.71428571428571
# AB12345 and AB12347: 78.57142857142857
# AB12346 and AB12347: 71.42857142857143