按列表中元素出现的次数对列表进行排序[重复]

发布于 2021-01-29 16:02:03

这个问题已经在这里有了答案

在排序时访问列表 (2个答案)

按频率排序列表 (7个答案)

去年关闭。

我想按列表中元素出现的次数对列表进行排序。
当我使用这种形式:

A=[2,1,3,4,2,2,3]
A.sort(key=lambda x:A.count(x))  
print(A)

结果不是我想要的:[2, 1, 3, 4, 2, 2, 3]
但是,当我使用编写类似的内容时sorted

B=sorted(A,key=lambda x:A.count(x))
print(B)

结果是正确的:[1, 4, 3, 3, 2, 2, 2]
这种行为的原因是什么?

关注者
0
被浏览
81
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这是有意设计的。当列表被适当排序时,CPython暂时“禁止”访问列表,该行为在此处记录

    CPython实现细节: 在对列表进行排序时,尝试使列表变异甚至检查的效果是不确定的。
    Python的C实现使列表在整个持续时间内显示为空,并在可以检测到列表在排序过程中发生突变的情况下引发ValueError。

    您可以通过A在键功能内部进行打印来检查它-您将得到一个 空列表

    In [2]: def key_function(x):
        ...:     print(A, x)
        ...:     return A.count(x)
        ...:
    
    In [3]: A.sort(key=key_function)  
    ([], 2)
    ([], 1)
    ([], 3)
    ([], 4)
    ([], 2)
    ([], 2)
    ([], 3)
    

    但是,如果您这样做是为了sorted()

    In [4]: sorted(A, key=key_function)
    ([2, 1, 3, 4, 2, 2, 3], 2)
    ([2, 1, 3, 4, 2, 2, 3], 1)
    ([2, 1, 3, 4, 2, 2, 3], 3)
    ([2, 1, 3, 4, 2, 2, 3], 4)
    ([2, 1, 3, 4, 2, 2, 3], 2)
    ([2, 1, 3, 4, 2, 2, 3], 2)
    ([2, 1, 3, 4, 2, 2, 3], 3)
    Out[4]: [1, 4, 3, 3, 2, 2, 2]
    

    它也记录在sort()实现中

    /* The list is temporarily made empty, so that mutations performed
     * by comparison functions can't affect the slice of memory we're
     * sorting (allowing mutations during sorting is a core-dump
     * factory, since ob_item may change).
     */.
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看