Why is this happening to my nested list? (Python)

Viewed 50
if __name__ == '__main__':
    records = []
    smallest = 0
    fat = int(input())
    for x in range(fat):
        name = input()
        score = float(input())
        records.append([name, score])
    records.sort(key=lambda x:x[1])
    print(records)
    for i in range(len(records)-3):
        if records[i][1] <= records[i+1][1]:
            del records[i]
        else:
            ''
print(records)

When I input this:

6
Jorge
3
Mia
3
Gus
5
Myles
4
Gerald
9
Fred
8

The output is [['Mia', 3.0], ['Gus', 5.0], ['Gerald', 9.0]]. I want to remove all the parts of the list with the lowest value. Why isn't this code working?

3 Answers

You have a sorted list of half a dozen records, with some scores being tied. Essentially you're doing this:

for i in range(3):
    if {i-th score smaller than next score}:
        del records[i]

That is very weird. Why? First, you are iterating over just half of the records. But worse, you are mutating the list you're iterating over, so it's unclear whether a given score will be compared with next score. Some scores will be compared, and some won't due to deletion + advancing to next index. That effectively skips an entry, skips the comparison of a pair of records.

Rather than deleting 2-element records in that way, consider defining 3-tuples with 3rd element initialized to False. Then set it True in the case where you want to delete, based on a comparison. Finally, return just those records that still have a False tombstone value.


Your <= comparsion will always be true, given that it is examining records that have already been placed into sorted order.

Perhaps you wanted < strictly less than, instead?

Since you sort the records, you can just take a slice of the resulting list that is from the 4th entry on, assuming that what you want is to remove the 3 entries with the smallest scores:

if __name__ == '__main__':

    records = [['Jorge', 3], ['Mia', 3], ['Gus', 5], ['Myles', 4], ['Gerald', 9], ['Fred', 8]]

    # records = []
    # fat = int(input())
    # for x in range(fat):
    #     name = input()
    #     score = float(input())
    #     records.append([name, score])

    records.sort(key=lambda x:x[1])

    print(records)

    records = records[3:]

    print(records)

Result:

[['Jorge', 3], ['Mia', 3], ['Myles', 4], ['Gus', 5], ['Fred', 8], ['Gerald', 9]]
[['Gus', 5], ['Fred', 8], ['Gerald', 9]]

I took out your input code in favor of a hard coded value to demonstrate the specific case you give in a reproducible way. I hate having to enter values to play around with code like this. You can easily put your input code back in by uncommenting it.

this is because u cant edit a list in side a loop, such as del.. so which operations that are all leading to the change in length wont work.. if the loop is working for a length of list

for this you can create a temp list and store the required values there.

Related