从.txt数字文件中查找Mutuals

时间:2018-05-31 15:06:57

标签: python

我已经为学校提供了这个代码,其目标是从代表人的值列表中列出所有互助(两个人互相请求的时间)。

我正在使用的列表是:

1,9,11,15,20,3 
2,29,22,5,21,8  
3,2,30,16,27,2
4,21,17,25,6,4
5,15,2,18,6,24
6,1,18,19,29,4
7,30,17,30,18,15
8,10,2,6,26,12
9,21,30,12,29,14

我必须找到互助的代码是:

i=0
j=0
k=0
l=0
mutuals = []
for i in range(0,8):
    for j in range(i+1, 8):
        for k in range(1,5):
            if content2[j][k] == content2[i][0]:
                for l in range(1,5):
                    if content2[j][0] == content2[i][l]:
                       mutuals.append(content2[i][0])
                       mutuals.append(content2[j][0])
                       #print(mutuals)
                       print(i,j,k,l)
                       l=0
                    print(i,j,k,l)
            print(i,j,k,l)
     print(i,j,k,l)
print(i,j,k,l)
print(mutuals)

我列出'print(i,j,k,l)'的原因是我可以试着看看代码中出了什么问题。

输出结果为:

['2','5'] 

即使应该还有['2','8']和['4','6'],我也无法弄清楚代码有什么问题。

如何修复代码以便其他几组相互作为输出打印?

3 个答案:

答案 0 :(得分:1)

您的问题是您使用range(start,stop) - “停止”值不具有包容性,因此如果您要测试最高n值,则需要n+1作为第二个论点。

#...
for i in range(0,9):
    for j in range(i+1, 9):
        for k in range(1,6):
            if content2[j][k] == content2[i][0]:
                for l in range(1,6):
#...

正如您所看到的,2的'共同'是其列表[2,29,22,5,21,8]中的最后一个参数,同样是6[6,1,18,19,29,4]的共同点。

由于lk的范围循环仅检查range(1,5),因此它们会停止检查最终条目,并且不会将它们识别为互为条件。

注意:您不需要初始化值i,j,k,l,因为它们会在for循环的第一次迭代中重置为{{的第一个值1}}。

您也不需要将range重置为l,因为它未使用(打印语句除外),直到在0循环中重置为止。

注意:因此可以采用更简单的方法:

for

答案 1 :(得分:0)

我没有使用大规模嵌套循环方法并跟踪一堆列表索引,而是建立一个对列表,以便您可以轻松测试它们之前是否已显示(除非您要去遇到内存问题,复制/修改数据没有坏处。)

requests = [
[1,9,11,15,20,3],
[2,29,22,5,21,8], 
[3,2,30,16,27,2],
[4,21,17,25,6,4],
[5,15,2,18,6,24],
[6,1,18,19,29,4],
[7,30,17,30,18,15],
[8,10,2,6,26,12],
[9,21,30,12,29,14]
]
all_pairs = []
#create one big list of pairs
for person in requests:
    pairs = []
    user_id = person[0]
    for other_person in person[1:]:
        pairs.append({user_id, other_person}) # add to the list of pairs (we use set so the order of the pair doesn't matter)
    all_pairs += pairs #add the pairs from one person to the global list

matches = []
#iterate over that list and check if we've seen that pair before
for index, pair in enumerate(all_pairs):
    if pair in pairs[:index]: #if we've seen it before
        matches.append(pair) #add it to our matches (if a pair is encountered a third time, it'll be added to matches twice)       

这可以写得更紧凑和有效,但我的目标是让它更容易理解流程。

答案 2 :(得分:0)

这不是调试代码,而是一种替代解决方案,它可以为您提供一些不同的方式来思考您的问题

# Load the data as given
c2 = [[1,9,11,15,20,3],
     [2,29,22,5,21,8 ], 
     [3,2,30,16,27,2],
     [4,21,17,25,6,4],
     [5,15,2,18,6,24],
     [6,1,18,19,29,4],
     [7,30,17,30,18,15],
     [8,10,2,6,26,12],
     [9,21,30,12,29,14]]

# Convert it to a dictionary where the key is the person, and
# the value is a set of people they requested
c3 = { l[0]: set(l[1:]) for l in c2}

# Now crudely iterate through each person checking if
# they appear in the requests for each person they
# requested.
m = set()
for me,l in c3.items():
    for them in l:
        if me != them and me in c3.get(them,set()):
            # add the pair as a sorted tuple and let the set
            # deduplicate
            m.add(tuple(sorted([me,them])))
print(m)

此输出

{(2, 5), (2, 8), (4, 6)}

这似乎效率低下,但大多数搜索都是使用set access完成的,这是一个恒定的时间。这些对被添加为元组,而不是列表,因为它们是不可变的,因此可以清除(你不能将列表放入集合中)。

这只是为了让您考虑使用不同的数据结构以及它们如何显着改变您的算法选择。

一旦掌握了这一点,那么整个循环就可以重写为集合理解

m = { tuple(sorted([me,them])) 
      for me in c3.keys() 
      for them in c3[me] 
      if me != them and me in c3.get(them,set())
     }