Home > Back-end >  How can I print the keys of a dictionary if a value matches?
How can I print the keys of a dictionary if a value matches?

Time:01-12

I have made a dictionary which you can see below,

dic1={'T1':{'ID':101,'Salary':20000,'ML':15,'DL':10,'CL':12,'P1':'8th','P2':'9th','P3':'10th','FP':4},
'T2':{'ID':102,'Salary':15000,'ML':15,'DL':10,'CL':12,'P4':'10th','P5':'7th','P6':'12th','FP':2},
'T3':{'ID':103,'Salary':15000,'ML':15,'DL':10,'CL':12,'P7':'5th','P8':'10th','P2':'12th','FP':1},
'T4':{'ID':104,'Salary':15000,'ML':15,'DL':10,'CL':12,'P4':'4th','P6':'9th','P1':'10th','FP':3}}

here I want to take user's input that which teacher is absent and then apply a loop which sees the periods(P1,P2 etc) stored in the details of teacher who is absent, then print the key(another teachers(T1,T2 etc)) which have the periods of absent teacher in their free period.

For referrence: Imagine teacher T1 is absent which have period 1,2,3(P1,P2,P3) respectively in classes. Now the loop prints the teachers who have period 1,2,3 in their free period(FP) respectively(i.e T2,T3,T4)

I have tried using different loops(one Is Given below) but not getting the output I want that I have told you earlier. So, please tell me if anyone has any solution or if I have to change anything in the dictionary which might help me in getting the required output.

a=input("Enter Teacher name")
k={key: val for key,val in dic1[a].items() if key.startswith('P')}
for i in dic1:
    for j in dic1[i].items():
        if j==k:
            print(i)
            print(k)
            print(j)
print(i)
print(k)
print(j)

CodePudding user response:

Great question! I'll answer in two parts, the first will address why your example loop is not working, and the second will provide a working solution (though it may not be particularly well optimised).

Part 1

Looking at your example, when you run your loop, j will be a tuple containing a key, value pair from each teacher's data. When you create k it is a dictionary. If you add a print statement before your if j==k: you will see what j and k are. Here is an example of the first few j's and k's for the first teacher:

j = ('ID', 101), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('Salary', 20000), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('ML', 15), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('DL', 10), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('CL', 12), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('P1', '8th'), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('P2', '9th'), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('P3', '10th'), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}
j = ('FP', 4), k = {'P1': '8th', 'P2': '9th', 'P3': '10th'}

As you can see, even when j = ('FP', 4), it is a tuple. When you test for equality by writing if j == k: it will fail as j is a tuple and k is a dict. The object type is compared during an equality test so this will fail. Note: equality tests are very strict so j and k must be exactly equal (type and contents) to return true.

Part 2

The following code should solve your problem. I've added comments to explain it line by line.

There are a couple of useful points to note.

  1. First we create a list of periods the teacher is absent from called target_periods. You'll note that I've replaced 'P' with '' and then cast the result as an integer. This makes sure that the period numbers are formatted the same way as the FP values we will compare to later on.
  2. Next when we start looping through the teachers, we need to skip the teacher that's absent.
  3. Finally, as we loop through the remaining teachers, we are only interested in their FP, so we can directly access that by its key and check if its in our list of target periods.

Let me know if you need any further clarifications.

a=input("Enter Teacher name")

# Get the periods of the absent teacher in a simple list
target_periods = [int(period.replace('P','')) for period in dic1[a].keys() if period.startswith('P')]

for teacher, data in dic1.items():  # Loop through the teachers and their data
    if teacher == a: # Skip the absent teacher
        continue
    elif data['FP'] in target_periods: # Check if the teacher has a period in common with the absent teacher
        print(f'Teacher: {teacher} has period {data["FP"]} in common with {a}')

CodePudding user response:

There's nothing really wrong with your dictionary - it can be used as is.

You first need to check if the teacher specified (input) is in the dictionary. If it is then isolate the Pn keys (their values are irrelevant). Add the numeric part of the Pn keys to a set.

Now iterate over the main dictionary. Ignore the input teacher. Get the FP value and check if it's in the previously constructed set.

Output accordingly:

dic1 = {'T1': {'ID': 101, 'Salary': 20000, 'ML': 15, 'DL': 10, 'CL': 12, 'P1': '8th', 'P2': '9th', 'P3': '10th', 'FP': 4},
        'T2': {'ID': 102, 'Salary': 15000, 'ML': 15, 'DL': 10, 'CL': 12, 'P4': '10th', 'P5': '7th', 'P6': '12th', 'FP': 2},
        'T3': {'ID': 103, 'Salary': 15000, 'ML': 15, 'DL': 10, 'CL': 12, 'P7': '5th', 'P8': '10th', 'P2': '12th', 'FP': 1},
        'T4': {'ID': 104, 'Salary': 15000, 'ML': 15, 'DL': 10, 'CL': 12, 'P4': '4th', 'P6': '9th', 'P1': '10th', 'FP': 3}}

teacher = input('Enter teacher name: ')

if teacher in dic1:
    p = set()
    for k in dic1[teacher].keys():
        if k.startswith('P'):
            p.add(int(k[1:]))
    for k, v in dic1.items():
        if k != teacher and v.get('FP') in p:
            print(k)
else:
    print('Unknown teacher')

Output:

T2
T3
T4
  • Related