计算两个列表中字母对匹配的组合?
我刚开始学习编程,找不到一个能准确回答我问题的问答(虽然有很多关于Python和在列表中匹配单词和字母的内容)。
我有两个这样的列表:
list1 = ["INTJ","ENTJ","ESTJ"]
list2 = ["INTP","ESFJ","ISTJ"]
总共有16种可能的字母组合。我已经计算出了字母组合的准确匹配数量,比如I/E(第一对)、S/N(第二对)、T/F(第三对)和P/J(第四对)。
我该如何记录有多少个准确的三字母、两字母和一字母匹配呢?这里有一些三字母匹配的例子:
ISTP and ISTJ (I + S + T)
INFP and INTP (I + N + P)
我得到了用户@thkang的帮助,计算字母对匹配的数量,但我不知道如何调整这段代码来跟踪匹配组合。我是否需要用其他方式来存储匹配结果才能实现这个目标?
matches = {0:0, 1:0, 2:0, 3:0}
for item1, item2 in zip(list1, list2):
for i in xrange(4):
if item1[i]==item2[i]:
matches[i] += 1
total_letters_compared = #length of a list * 4
total_correct_matches = #sum(matches.values())
nth_letter_pair_matches = #matchs[n-1]
这是我写的代码,但我意识到这段代码实在是太糟糕了。有人能帮我把它改好吗?
matches = {0:0, 1:0, 2:0, 3:0}
four_letter_matches = 0
three_letter_matches = 0
two_letter_matches = 0
for item1, item2 in zip(actual, typealyzer):
if item1[0:2] == item2[0:2]\
or item1[0], item1[1], item1[3] == item2[0], item2[1], item2[3]\
or item1[1], item1[2], item1[3] == item2[1], item2[2], item2[3]\
or item1[0], item1[2], item1[3] == item2[0], item2[2], item2[3]:
three_letter_matches = three_letter_matches + 1
elif item1[0:1] == item2[0:1]\
or item1[0], item1[1] == item2[0], item2[1]\
or item1[0], item1[2] == item2[0], item2[2]\
or item1[0], item1[3] == item2[0], item2[3]\
or item1[1], item1[2] == item2[1], item2[2]\
or item1[1], item1[3] == item2[1], item2[3]:
#and so forth...
two_letter_matches = two_letter_matches + 1
#I think I can get the one-letter matches by matches[1] or matches[2] or matches[3] or matches[4]
for i in xrange(4):
if item1[i]==item2[i]:
matches[i] += 1
我想能够分别打印出三字母、两字母和一字母的匹配结果,想办法做到这一点。
print str(three_letter_matches)
print str(two_letter_matches)
print str(one_letter_matches)
2 个回答
0
如果我理解你的问题没错的话,你可以通过以下方式来追踪所有匹配的组合:
list1 = ['INTJ','ENTJ','ESTJ']
list2 = ['INTP', 'ESFJ', 'ISTJ']
import collections
import itertools
matches = collections.defaultdict(list)
for item1,item2 in itertools.product(list1,list2):
match = ''
for i in xrange(4):
if item1[i] == item2[i]:
match += item1[i]
if len(match):
matches[match].append((item1,item2))
在这里,matches
最终会变成:
{'ITJ': [('INTJ', 'ISTJ')],
'EJ': [('ENTJ', 'ESFJ')],
'INT': [('INTJ', 'INTP')],
'J': [('INTJ', 'ESFJ')],
'STJ': [('ESTJ', 'ISTJ')],
'TJ': [('ENTJ', 'ISTJ')],
'T': [('ESTJ', 'INTP')],
'NT': [('ENTJ', 'INTP')],
'ESJ': [('ESTJ', 'ESFJ')]}
如果你只是想计算某个匹配出现的次数,你可以把代码修改成这样:
list1 = ['INTJ','ENTJ','ESTJ']
list2 = ['INTP', 'ESFJ', 'ISTJ']
import collections
import itertools
matches = collections.defaultdict(lambda: 0)
for item1,item2 in itertools.product(list1,list2):
match = ''
for i in xrange(4):
if item1[i] == item2[i]:
match += item1[i]
if len(match):
matches[match] += 1
这样就会得到:
{'ITJ': 1, 'EJ': 1, 'INT': 1, 'J': 1, 'STJ': 1, 'TJ': 1, 'T': 1, 'NT': 1, 'ESJ': 1}
0
import itertools as IT
import collections
list1 = ["INTJ","ENTJ","ESTJ"]
list2 = ["INTP","ESFJ","ISTJ"]
matches = collections.Counter()
for item1, item2 in zip(list1, list2):
for n in range(1,4):
for idx in IT.combinations(range(4), n):
if all(item1[i] == item2[i] for i in idx):
print(item1, item2, idx)
matches[n] += 1
print(matches)
结果
% test.py
('INTJ', 'INTP', (0,))
('INTJ', 'INTP', (1,))
('INTJ', 'INTP', (2,))
('INTJ', 'INTP', (0, 1))
('INTJ', 'INTP', (0, 2))
('INTJ', 'INTP', (1, 2))
('INTJ', 'INTP', (0, 1, 2))
('ENTJ', 'ESFJ', (0,))
('ENTJ', 'ESFJ', (3,))
('ENTJ', 'ESFJ', (0, 3))
('ESTJ', 'ISTJ', (1,))
('ESTJ', 'ISTJ', (2,))
('ESTJ', 'ISTJ', (3,))
('ESTJ', 'ISTJ', (1, 2))
('ESTJ', 'ISTJ', (1, 3))
('ESTJ', 'ISTJ', (2, 3))
('ESTJ', 'ISTJ', (1, 2, 3))
Counter({1: 8, 2: 7, 3: 2})
我加了一个额外的打印语句,来显示找到的匹配内容。
('ESTJ', 'ISTJ', (2, 3))
这表示两个列表在第2和第3个位置上匹配,也就是字母T和J。
Counter({1: 8, 2: 7, 3: 2})
这表示有八个1个字母的匹配,七个2个字母的匹配,还有两个3个字母的匹配。