在python中仅一次比较多个列表

时间:2019-05-29 08:31:09

标签: python list loops

我遇到一些代码问题。我希望我的代码比较包含多个列表的列表中包含的两个列表,但每个列表仅一次。

resultList = [
    ['Student1', ['Sport', 'History']],
    ['Student2', ['Math', 'Spanish']],
    ['Student3', ['French', 'History']],
    ['Student4', ['English', 'Sport']],
]

for list1 in resultList:
    for list2 in resultList:
        i = 0
        for subject in list1[1]:
            if subject in list2[1]:
                if list2[1].index(subject) >= list1[1].index(subject):
                    i+=1
                else:
                    i+=2
        print(list1[0] + ' - ' + list2[0] + ' : ' + str(i))

此打印:

Student1 - Student1 : 2
Student1 - Student2 : 0
Student1 - Student3 : 1
Student1 - Student4 : 1
Student2 - Student1 : 0
Student2 - Student2 : 2
Student2 - Student3 : 0
Student2 - Student4 : 0
Student3 - Student1 : 1
Student3 - Student2 : 0
Student3 - Student3 : 2
Student3 - Student4 : 0
Student4 - Student1 : 2
Student4 - Student2 : 0
Student4 - Student3 : 0
Student4 - Student4 : 2

我想要这个结果:

Student1 - Student1 : 2
Student1 - Student2 : 0
Student1 - Student3 : 1
Student1 - Student4 : 1
Student2 - Student2 : 2
Student2 - Student3 : 0
Student2 - Student4 : 0
Student3 - Student3 : 2
Student3 - Student4 : 0
Student4 - Student4 : 2

感谢您的帮助!

6 个答案:

答案 0 :(得分:4)

为此,我会使用itertools.combinations_with_replacementitertools.combinations

In [1]: resultList = [
   ...:     ['Student1', ['Sport', 'History']],
   ...:     ['Student2', ['Math', 'Spanish']],
   ...:     ['Student3', ['French', 'History']],
   ...:     ['Student4', ['English', 'Sport']],
   ...: ]
   ...:

In [2]: import itertools
In [3]: new_result = itertools.combinations_with_replacement(resultList, 2)
In [4]: for lists_tuple in new_result:
    ...:     list1, list2 = lists_tuple
    ...:     i = 0
    ...:     for subject in list1[1]:
    ...:         if subject in list2[1]:
    ...:             if list2[1].index(subject) >= list1[1].index(subject):
    ...:                 i+=1
    ...:             else:
    ...:                 i+=2
    ...:     print(list1[0] + ' - ' + list2[0] + ' : ' + str(i))
    ...:
    ...:
Student1 - Student1 : 2
Student1 - Student2 : 0
Student1 - Student3 : 1
Student1 - Student4 : 1
Student2 - Student2 : 2
Student2 - Student3 : 0
Student2 - Student4 : 0
Student3 - Student3 : 2
Student3 - Student4 : 0
Student4 - Student4 : 2

combinations

如果您决定不想将每个列表与其自身进行比较(Student1-Student1),请将combinations_with_replacement更改为combinations,您将获得列表的不同元素:

Student1 - Student2 : 0
Student1 - Student3 : 1
Student1 - Student4 : 1
Student2 - Student3 : 0
Student2 - Student4 : 0
Student3 - Student4 : 0

答案 1 :(得分:2)

您可以使用set.intersection来比较列表:

resultList = [
    ['Student1', ['Sport', 'History']],
    ['Student2', ['Math', 'Spanish']],
    ['Student3', ['French', 'History']],
    ['Student4', ['English', 'Sport']],
]

s = set()
for list1 in resultList:
    for list2 in resultList:
        i = tuple(sorted([list1[0], list2[0]]))
        if i in s:
            continue
        s.add(i)
        print(list1[0], list2[0], len(set(list1[1]).intersection(list2[1])))

打印:

Student1 Student1 2
Student1 Student2 0
Student1 Student3 1
Student1 Student4 1
Student2 Student2 2
Student2 Student3 0
Student2 Student4 0
Student3 Student3 2
Student3 Student4 0
Student4 Student4 2

答案 2 :(得分:2)

这个想法与@yatu的答案类似,但是您可以使用enumerate而不是手动保持计数,并且仅对list2中当前索引之后的list1的一部分进行迭代。如果要避免1-1 2-2对,只需使用resultList[idx+1:]而不是resultList[idx:]

resultList = [                                                                                                                 
    ['Student1', ['Sport', 'History']],                                                                                        
    ['Student2', ['Math', 'Spanish']],                                                                                         
    ['Student3', ['French', 'History']],                                                                                       
    ['Student4', ['English', 'Sport']],                                                                                        
]                                                                                                                              

for idx, list1 in enumerate(resultList):                                                                                       
    for list2 in resultList[idx:]:                                                                                             
        i = 0                                                                                                                  
        for subject in list1[1]:                                                                                               
            if subject in list2[1]:                                                                                            
                if list2[1].index(subject) >= list1[1].index(subject):                                                         
                    i+=1                                                                                                       
                else:                                                                                                          
                    i+=2                                                                                                       
        print(list1[0] + ' - ' + list2[0] + ' : ' + str(i))

答案 3 :(得分:1)

与原始版本相比,具有两个修改行和两个新行的

版本:

resultList = [
['Student1', ['Sport', 'History']],
['Student2', ['Math', 'Spanish']],
['Student3', ['French', 'History']],
['Student4', ['English', 'Sport']],
]

for index1 in range(0,len(resultList)):
    for index2 in range(index1, len(resultList)):
        i = 0
        list1 = resultList[index1]
        list2 = resultList[index2]
        for subject in list1[1]:
            if subject in list2[1]:
                if list2[1].index(subject) >= list1[1].index(subject):
                    i+=1
                else:
                    i+=2
        print(list1[0] + ' - ' + list2[0] + ' : ' + str(i))

答案 4 :(得分:1)

您应该做得更清楚

只有2个循环,只有3行:

for i in resultList:
    for j in resultList[resultList.index(i):]:
            print(str(i[0]) + '-' + str(j[0]) + ' : ' + str((np.isin(i[1], j[1]) == True).sum()))

结果:

Student1-Student1 : 2
Student1-Student2 : 0
Student1-Student3 : 1
Student1-Student4 : 1
Student2-Student2 : 2
Student2-Student3 : 0
Student2-Student4 : 0
Student3-Student3 : 2
Student3-Student4 : 0
Student4-Student4 : 2

不客气:)

答案 5 :(得分:0)

我认为,您应该更清楚地做到这一点:)。

也许可以使用OOP尝试这种方式:

import itertools.combinations

class Student:
    def __init__(self, name, subjects):
        self.name = name
        self.subjects = subjects

    def compare_to(self, another_student):
        result = 0
        for subject_my in self.subjects:
            for subject_he in another_student.subjects:
                if self.subjects.index(subject_my) >= \   
                        another_student.subjects.index(subject_he):
                    result+=1
                else:
                    result+=2
       return result

resultList = [
    Student('Student1', ['Sport', 'History']),
    Student('Student2', ['Math', 'Spanish']),
    Student('Student3', ['French', 'History']),
    Student('Student4', ['English', 'Sport'])
    ]

for first, secound in itertools.combinations(resultList):
    print("{} - {} : {}".format(first.name, secound.name, first.compare_to(secound)))

我认为,它应该看起来更干净,更易读:)。选择当然是您的。 清晰的代码,将简化您发现问题所在的机会。