从一个包含数字的.txt文件中查找相互关系

2024-10-04 03:29:05 发布

您现在位置: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'],我很难找出代码的错误。你知道吗

如何修复代码,以便将其他相互关系集也打印为输出?你知道吗


Tags: 代码in目标列表forif关系错误
3条回答

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

# 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完成的,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())
     }

与大规模嵌套的循环方法和跟踪一堆列表索引不同,我将建立一个成对的列表,这样您就可以轻松地测试它们以前是否出现过(除非您将遇到内存问题,否则复制/修改数据不会有任何伤害)。你知道吗

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)       

这可以写得更简洁、更高效,但我的目标是让它更容易理解流程。你知道吗

你的问题是你使用了range(start,stop)-'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的'mutual'是其列表[2,29,22,5,21,8]中的最后一个参数,与6[6,1,18,19,29,4]的mutual一样。你知道吗

由于lk的范围循环只检查range(1,5),它们在检查最后一个条目之前就停止了,并且不会将它们识别为相互的。你知道吗


注意:您不需要初始化值i,j,k,l,因为它们在for循环的第一次迭代中被重置为range的第一个值。你知道吗

您也不需要将l重置为0,因为它在其for循环中重置之前是未使用的(print语句中除外)。你知道吗


注意:实现这一点的更简单方法是:

for entry in nums:
    for test in nums[entry[0]:]:
        if entry[0] in test[1:] and test[0] in entry[1:]:
            print test[0], entry[0]

相关问题 更多 >