为什么我的嵌套列表会发生这种情况?(蟒蛇)

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

提问人:Ski 提问时间:9/22/2022 最后编辑:CoderioSki 更新时间:9/22/2022 访问量:78

问:

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)

当我输入这个时:

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

输出为 。我想删除列表中值最低的所有部分。为什么这段代码不起作用?[['Mia', 3.0], ['Gus', 5.0], ['Gerald', 9.0]]

Python 列表 循环 for-loop 嵌套列表

评论

1赞 Tim Roberts 9/22/2022
因为您正在修改正在循环访问的列表。循环范围是在您进入循环时设置的,但在循环中,您正在更改列表。删除项目 0 后,曾经是项目 1 的内容将变为项目 0。为此,请创建一个新列表,然后复制要保留的项目。
0赞 CryptoFool 9/22/2022
在第二个循环中,您既要删除一个条目,又要向前移动 pointer()。这具有跳过记录的效果,当您将新记录移动到指向的位置时,然后增加以跳过它。我认为只有在不删除条目时才要增加。我不明白你为什么需要比较。您已经对列表进行了排序,那么比较不会总是正确的吗?iiii

答:

0赞 J_H 9/22/2022 #1

你有一个由六条记录组成的排序列表, 一些比分被打平。 从本质上讲,您正在这样做:

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

这很奇怪。 为什么? 首先,您只迭代了一半的记录。 但更糟糕的是,你正在改变你正在迭代的列表, 因此,目前尚不清楚给定的分数是否会与下一个分数进行比较。 有些分数会比较,有些则不会 由于删除 + 前进到下一个索引。 这有效地跳过了一个条目,跳过了一对记录的比较。

与其以这种方式删除 2 元素记录,不如考虑 定义 3 元组,其中第 3 个元素初始化为 。 然后在要删除的情况下设置它, 基于比较。 最后,只返回那些仍然存在的记录 逻辑删除值。FalseTrueFalse


你的比较永远是正确的, 鉴于它正在检查具有 已按排序顺序排列。<=

也许你想要严格低于,相反?<

0赞 CryptoFool 9/22/2022 #2

由于您对记录进行了排序,因此您可以只从第 4 个条目开始的结果列表中取一部分,假设您想要删除分数最小的 3 个条目:

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)

结果:

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

我拿出了你的输入代码,转而使用硬编码值,以可重复的方式演示你给出的具体情况。我讨厌必须输入值来玩弄这样的代码。您可以通过取消注释轻松地将输入代码放回原处。

-2赞 Ares_5919 9/22/2022 #3

这是因为您无法在循环中编辑列表,例如 del.。因此,哪些操作都会导致长度变化,这将不起作用。如果循环在列表长度内工作

为此,您可以创建一个临时列表并将所需的值存储在其中。