【问题标题】:question about custom sorting using key argument in sorted()关于在 sorted() 中使用 key 参数进行自定义排序的问题
【发布时间】:2019-05-17 05:32:17
【问题描述】:

我正在尝试了解我收到错误消息的原因。

我正在尝试使用自定义函数对字典进行排序。我意识到我可以使用 lambda 来实现相同的目标,以及首先将字典排序为元组,但我真正想做的是了解为什么我的函数没有返回列表。

sample_dict = {"a":4,"b":2,"c":7,"d":9}

def all_values(x):
    return list(x.values())

print(sorted(sample_dict, key = all_values))

期望 return list(x.values()) 返回要在排序键参数中使用的列表,但相反,我收到了错误消息:

AttributeError: 'str' 对象没有属性 'values'

【问题讨论】:

    标签: python-3.x


    【解决方案1】:

    您的意思是根据值对键进行排序。

    key 函数旨在将字典键转换为可比较的值(如果省略它,就像传递一个标识函数,您是在对字典键本身进行比较)。你想从键中返回值,所以它是一个字典访问:

    sample_dict = {"a":4,"b":2,"c":7,"d":9}
    
    def all_values(x):
        return sample_dict[x]
    
    print(sorted(sample_dict, key = all_values))
    

    您希望字典在key 中传递,这根本没有兴趣。 key 必须在每次调用时都不同,sort 确实如此。

    使用lambda 当然更短

    print(sorted(sample_dict, key = lambda x: sample_dict[x]))
    

    但是传递一个真正的函数可以更容易地插入副作用:

    def all_values(x):
        print("key input",x)
        return sample_dict[x]
    

    这样您就可以了解 sort 正在做什么(最终结果由主打印语句打印):

    key input b
    key input a
    key input c
    key input d
    ['b', 'a', 'c', 'd']
    

    现在你明白为什么list('b'.values()) 失败了。

    【讨论】:

    • 有没有更简单的方法来告诉键只获取值,比如operator,itemgetter@Jean?
    • 不是那种情况。 operator.itemgetter 不是这样工作的。你仍然需要一个 lambda / 它会很麻烦:stackoverflow.com/questions/48023356/…
    • 啊,非常感谢。正如其他人提到的那样,我似乎完全不知道关键论点实际上在做什么。
    【解决方案2】:

    我认为您对 key 参数的工作方式感到困惑。
    本质上,它将给定函数映射到可迭代的所有元素上,然后 sorted 根据映射的输出进行排序。
    事实上,当你对sample_dict 进行排序时,你就是在对它的键进行排序,也就是字符串:

    sample_dict = {"b":2, "c":7, "d":9, "a":4}
    print(sorted(sample_dict))
    # ['a', 'b', 'c', 'd']
    

    如果我尝试将all_values 映射到这个字符串列表:

    list(map(all_values, sample_dict))
    
    # AttributeError: 'str' object has no attribute 'values'
    

    all_values 必须在输入中得到一个字符串,就像@Jean-FrançoisFabre 建议的那样:

    def all_values(x):
        return sample_dict[x]
    
    print(sorted(sample_dict, key = all_values))
    # ['b', 'a', 'c', 'd']
    

    【讨论】:

      猜你喜欢
      • 2012-07-27
      • 2021-10-07
      • 2013-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多