简体   繁体   中英

Alternative to nested for loops in Python3

I have a piece of code that compares a student's skill level to an assignment's difficulty level. It tries to match the student's level to the highest possible assignment difficulty. I have achieved success using two nested for loops. However, it is incredibly inefficient when the number of values increases.

    def maxAssignmentPoints(self, difficulty, points, student) -> int:
        global totalPoints
        totalPoints = 0
        for i in range(len(student)):
            for j in range(len(difficulty)):
                if student[i] > difficulty[j]:
                    try:
                        if student[i] < difficulty[j + 1]:
                            totalPoints += points[j]
                    except IndexError:
                        break
                if student[i] == difficulty[j]:
                    totalPoints += points[j]
        return str(totalPoints)

I have also looked into using itertools.product but I'm unsure on how to compare the two variables in the Cartesian product. results = list(product(student, difficulty)) produces (1,1) (1,2) (1,3) (2,1)... and so on. Is there any way to compare the values in the pair?

You write: "However, it is incredibly inefficient when the number of values increases." Why? The more data, the more time it takes to process it. I don't think nested loops are an “incredible” issue for the performance of your function. Performance can be increased by using the most appropriate data structures and their processing algorithms.

As for your function, it can be rewritten in a more readable form:

def max_assignment_points(difficulties: list, points: list, students: list) -> int:
    total_points = 0
    for student in students:
        for i in range(len(difficulties) - 1):
            if difficulties[i] < student < difficulties[i + 1]:
                total_points += points[i]
            elif student == difficulties[i]:
                total_points += points[i]
    return total_points

PS

Firstly, it's a bad idea to use a global variable inside a function and change it at the same time. What prevents you from declaring a local variable?

Secondly, when declaring a function, you wrote that it returns an int value, but in fact it returns a str .

Thirdly, using an exception to get out of a loop seems very strange.

I dont think more loops are bad here, but efficient Data-Structures will come in handy. You can keep ranges of difficulty in a dictionary - in the format:

scores = dict(zip(difficulty, points))

Now I feel its more organized than before.

def maxAssignmentPoints(self, students, scores) -> int:
    totalPoints = 0
    for student in range(students):
        if scores.get(student, None) is not None:
            total_points += scores[student]
    return str(totalPoints)

Let me know if this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM