【问题标题】:why does the sort(with key) function not work as intended? [duplicate]为什么 sort(with key) 功能不能按预期工作? [复制]
【发布时间】:2022-03-02 17:33:05
【问题描述】:
# A function that returns the frequency of each value:
def myFunc(e):
     return cars.count(e)

cars = ['Ford', 'Ford', 'Ford', 'Mitsubishi','Mitsubishi', 'BMW', 'VW']

cars.sort(key=myFunc) 

print(cars)

输出:

['Ford', 'Ford', 'Ford', 'Mitsubishi', 'Mitsubishi', 'BMW', 'VW']

我的期望:

['BMW', 'VM', 'Mitsubishi', 'Mitsubishi', 'Ford', 'Ford', 'Ford']

计数:

Ford - 3
Mitsubishi - 2
BMW - 1
VM - 1

它应该按列表中计数的升序排序。

【问题讨论】:

    标签: python list sorting


    【解决方案1】:

    问题是您在 key 函数中使用 cars,但 .sort 是就地的。这会导致cars 在对关键函数的中间调用中不可靠。

    如果我们在 key 函数中打印cars 就可以看到问题:

    def myFunc(e):
        print(cars)
        return cars.count(e)
    
    
    cars = ['Ford', 'Ford', 'Ford', 'Mitsubishi', 'Mitsubishi', 'BMW', 'VW']
    
    cars.sort(key=myFunc)
    

    这个输出

    []
    []
    []
    []
    []
    []
    []
    

    所以cars.count 将返回0,无论传递什么元素,并且列表将保留其原始顺序

    使用不在位的sorted(...)

    def myFunc(e):
        return cars.count(e)
    
    
    cars = ['Ford', 'Ford', 'Ford', 'Mitsubishi', 'Mitsubishi', 'BMW', 'VW']
    
    cars = sorted(cars, key=myFunc)
    
    print(cars)
    

    这个输出

    ['BMW', 'VW', 'Mitsubishi', 'Mitsubishi', 'Ford', 'Ford', 'Ford']
    

    附带说明一下,在这种情况下,您可以直接使用cars.count,而无需定义包装函数:

    cars = sorted(cars, key=cars.count)
    

    【讨论】:

    • 附带说明,您无需重新定义myFunc;您可以直接拨打cars = sorted(cars, cars.count)
    • @Stef 确实,我会添加评论
    • @Stef 您将需要关键字 - 即 cars = sorted(cars, key=cars.count)
    • 我会删除“中级”这个词。这听起来像是一个神话,即在实际排序期间而不是在实际排序开始之前之前为每次比较调用键函数。
    【解决方案2】:

    这个问题是因为您在修改函数时引用了汽车。

    如果您获得副本,则不会发生这种情况:

    def myFunc(e):
         return cars.count(e)
    
    cars = ['Ford', 'Ford', 'Ford', 'Mitsubishi','Mitsubishi', 'BMW', 'VW']
    
    cars2 = cars.copy()
    
    cars2.sort(key=myFunc) 
    
    print(cars2)
    # ['BMW', 'VW', 'Mitsubishi', 'Mitsubishi', 'Ford', 'Ford', 'Ford']
    

    也就是说,这种方法效率不高,因为您需要再次阅读每个元素的整个列表。

    改为使用计数器:

    from collections import Counter
    
    cars = ['Ford', 'Ford', 'Ford', 'Mitsubishi','Mitsubishi', 'BMW', 'VW']
    c = Counter(cars)
    
    cars.sort(key=c.get)
    
    print(cars)
    # ['BMW', 'VW', 'Mitsubishi', 'Mitsubishi', 'Ford', 'Ford', 'Ford']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 2021-02-24
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 2021-05-30
      • 2020-03-05
      相关资源
      最近更新 更多