使用字典嵌套FOR循环.如何从第一个FOR使用的值开始检查第二个FOR



所以我有一个字典,其中标签是患者代码或姓名(字符串(,相关的数字是会诊时间(int(。例如,我有这样的:{'0001': 15, 'Charles': 20}"0001"需要15分钟咨询,"Charles"需要20分钟咨询。

我事先不知道哪里有识别一个人的名字或号码(但它们都是字符串(,也就是说,我不知道Charles在字典中的位置,甚至不知道它是否存在

我想运行这本词典来检查有相同咨询时间的患者,如果他们有,我想运行某个不相关的功能。现在我有这个:

for pat_i in self.MD_dict:
for pat_j in self.MD_dict:
if(self.MD_dict[pat_i]==self.MD_dict[pat_j]):
aux=aux+1
funtion(pat_i, pat_j);

然而,我希望j从I+1开始。我该怎么做?

我试着使用测距功能:

for pat_i in range(len(self.MD_dict)):
for pat_j in range(i+1,len(self.MD_dict)):
if(self.MD_dict[pat_i]==self.MD_dict[pat_j]):
aux=aux+1
funtion(pat_i, pat_j);

但是因为pat_i可能是一个字符串,所以它不起作用。例如,在pat_i=1和pat_j=2的情况下,if工作所需的代码为"0001"和Charles。但是自从pat_i!='0001'和pat_j!='Charles的不起作用

在原始字典中,患者名称/id是关键字,时间是值。在新字典中,时间是关键字,paitent-name/id列表是值。

这是一个制作字典进行反向查找的想法,然后将具有相同时间的患者姓名/id组合到一个列表中。

def make_inverse_dict(x):
# Time is key. List of patients is value
time_dict = {}
for name, time in x.items():
if time in time_dict:
time_dict[time].append(name)
else:
time_dict[time] = [name]
return time_dict

def f(p1, p2):
print(f"    {p1}, {p2}")

def make_patient_pair(patient_list):
# Triangular loop to make pairs of patients 
# without duplication
n_patients = len(patient_list)
out = []
for i in range(n_patients):
for j in range(i):
pair = (patient_list[i], patient_list[j])
out.append(pair)
return out

def main():
patient_dict = {'0001': 15,
'0002': 10,
'Charles': 20,
'Ann': 20,
'0003': 15}
time_dict = make_inverse_dict(patient_dict)
for time, patient_list in time_dict.items():
n_patients = len(patient_list)
print("time: ", time)
if n_patients > 1:
for p1, p2 in make_patient_pair(patient_list):
f(p1, p2)

main()

结果:

time:  15
0003, 0001
time:  10
time:  20
Ann, Charles

代码的问题是您要多次迭代它。在第二次迭代中,检查MD_dict[pat_i]是否等于MD_dict[pat_j]。这意味着你将获得双倍的数据量,因为在某一点上,第二个循环将到达与第一个循环所在的点完全相同的点;查尔斯,";第二循环将首先在开始处开始,然后它将最终到达"0";查尔斯"显然;Charles";不会在第一个循环和第二个循环之间发生变化——这将导致一个实例,在该实例中;Charles";以及";Charles";进入你的功能,这不是你想要的。

假设MD_dict是:

MD_dict = {'0001': 15, 'Charles': 20, '0002':15, 'Alex': 20, 'Jack':15}

我们能做的是使用enumerate来确保这些重复不会发生:

pats = list(MD_dict.keys())
enum = list(enumerate(pats))

上面,enum将患者的姓名和他们出现的索引配对:

[(0, '0001'), (1, 'Charles'), (2, '0002'), (3, 'Alex'), (4, 'Jack')]

然后,我们可以在enum上迭代两次:

for x, pat_i in enum:
for y,pat_j in enum:
if x != y and MD_dict[pat_i] == MD_dict[pat_j]:
function(pat_i, pat_j) # apply function here

请注意x != y在条件语句中的显示方式。这是为了避免将同一个人与自己配对。这确保了第二个循环不会考虑第一个循环所在的人。结果是:

function(0001, 0002)       # consult times == 15
function(0001, Jack)       # consult times == 15
function(Charles, Alex)    # consult times == 20
function(0002, 0001)       # consult times == 15
function(0002, Jack)       # consult times == 15
function(Alex, Charles)    # consult times == 20
function(Jack, 0001)       # consult times == 15
function(Jack, 0002)       # consult times == 15

然而,上面的函数有一个问题,我不完全清楚你在这个问题中要求什么。这个问题是该函数将被应用于";Charles";以及";Alex";然后";Alex";以及";Charles";这是因为我们把字典翻了两遍,所以它会找到";Alex";作为当第一循环命中"0"时的匹配;Charles";并且它将拾取";Charles";作为当第一循环命中"0"时的匹配;亚历克斯"如果这不是你想要的,我们可以在第二个循环上切片enum

pats = list(MD_dict.keys())
enum = list(enumerate(pats))
for x, pat_i in enum:
for y,pat_j in enum[x+1:]:
if MD_dict[pat_i] == MD_dict[pat_j]:
function(pat_i, pat_j) # apply function here

上面,for y,pat_j in enum[x+1:]将只考虑第一个循环打开的人后面的人。然后我们不必检查x != y。输出如下:

function(0001, 0002)      # consult times == 15
function(0001, Jack)      # consult times == 15
function(Charles, Alex)   # consult times == 20
function(0002, Jack)      # consult times == 15
sorted_items = sorted(self.MD_dict.items(), key=lambda x: x[1])
for i, (pat_i, pat_i_val) in enumerate(sorted_items):
for (pat_j, pat_j_val) in sorted_items[i+1:]
if pat_i_val == pat_j_val:
aux=aux+1
funtion(pat_i, pat_j)

相关内容

  • 没有找到相关文章

最新更新