【问题标题】:Sorting a Dictionary by Key and then Value (list or tuple?)按键然后按值对字典进行排序(列表还是元组?)
【发布时间】:2018-10-10 00:03:17
【问题描述】:

我有一本字典

dict = {key: [a, b, c, d]}

key是一个str,a是一个数字,b是一个数字,c是一个数字,d是一个数字。

如何打印我的字典,首先按 d 中的数字排序,然后按键中字符串的长度(最大在前)?

我尝试使用类似的东西...

for key in sorted(dict.items(), key=lambda x: (-len(x[0]), x[1][3])):

但我不断收到属性错误。

【问题讨论】:

  • 确切的错误消息是什么(编辑问题以将其显示为格式正确的文本)?
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。由于未定义的变量,您发布的代码无法执行。
  • sorted(your_dict.items(), key=lambda t: (t[1][-1], len(t[0])))
  • @dawg:他们首先想要最长的密钥(等于d),所以添加一个- 使其成为-len(t[0])
  • @ShadowRanger:是的——我在回答中解决了这个问题。谢谢!

标签: python python-3.x algorithm sorting bioinformatics


【解决方案1】:

你可以这样做:

>>> dictionary = {'aaaa': [1,2,2,3], 'aa': [1,2,2,3], 'aaa': [2,2,2,2], 'a': [4,2,2,6]}
>>> arr = sorted(dictionary.items(), key=lambda x: (-x[1][3],-len(x[0])))
>>> for k in arr:
        print(k)

('a', [4, 2, 2, 6])
('aaaa', [1, 2, 2, 3])
('aa', [1, 2, 2, 3])
('aaa', [2, 2, 2, 2])

注意:首先按较大的d排序,然后再按较大的key排序。

要颠倒任何优先级的顺序,只需尝试在lambda 函数的元组中的元素中删除/保留-

【讨论】:

  • 我不是指d 的降序排列。降序约束仅适用于键字符串长度。
  • @slider 是的,刚刚更新了答案:P 排序选择是任意的,这是一个概念验证而不是万无一失的解决方案:D
【解决方案2】:

除非您使用 Python 3.6+,否则字典是无序集合。因此,我假设您想根据您的 2 个标准构建一个 OrderedDict。为此,您可以将 sorted 与自定义键一起使用,然后提供给 OrderedDict

from collections import OrderedDict

d = {'ads': [4, 6, 1, 4], 'bs': [1, 3, 1, 9], 'cfsdg': [6, 1, 5, 4], 'ddsf': [5, 1, 6, 4]}

res = OrderedDict(sorted(d.items(), key=lambda x: (x[1][-1], -len(x[0]))))

OrderedDict([('cfsdg', [6, 1, 5, 4]),
             ('ddsf', [5, 1, 6, 4]),
             ('ads', [4, 6, 1, 4]),
             ('bs', [1, 3, 1, 9])])

【讨论】:

  • OP 不需要对 dict 本身进行排序。他们只想按排序顺序打印它。这里不需要OrderedDict
  • @ShadowRanger “Print my dict sorted”是一个我觉得模棱两可的短语。你可以说它与“打印一个排序的字典”不同,但形容词实际上可以在这样一个短语中的对象之前或之后任意。
【解决方案3】:

(无耻盗用 jpp 的示例字典)

你可以这样做:

di = {'ads': [4, 6, 1, 4], 'bs': [1, 3, 1, 9], 'cfsdg': [6, 1, 5, 4], 'ddsf': [5, 1, 6, 4]}
print('\n'.join(map(str, sorted(di.items(), key=lambda t: (t[1][-1], -len(t[0]))))))

打印:

('cfsdg', [6, 1, 5, 4])
('ddsf', [5, 1, 6, 4])
('ads', [4, 6, 1, 4])
('bs', [1, 3, 1, 9])

【讨论】:

    【解决方案4】:

    您的代码有效,但可能不是您正在寻找的“正确”行为,因为您使用了错误的负号。您的“key”变量可能有问题,因为当您使用dict.items() 进行排序时,它会返回一个带有(key, value) 的元组

    这是一个远景,但我猜你正在尝试这样做?

    for key in sorted(dict.items(), key=lambda x: (-len(x[0]), x[1][3])):
        print(dict[key])
    

    这是不正确的,因为“key”返回一个元组。

    要以更容易理解的方式执行此操作,请执行以下操作。

    for key, value in sorted(d.items(), key=lambda x: (x[1][-1], -len(x[0]))):
        print(key, value)
    

    为什么它返回一个元组列表?因为dict.items() 是一个元组列表,而您正在对该元组列表进行排序,而不是字典对象。

    【讨论】:

      【解决方案5】:

      您可以保持字典完整并对其进行排序,使用 dict() 构造函数

      d = dict(sorted(d.items(), key=lambda x: (x[1][3], -len(x[0]))))
      # {'stampede': [4, 2, 1, 1], 'the': [3, 3, 2, 1], 'vash': [1, 2, 3, 4]}
      

      【讨论】:

        猜你喜欢
        • 2012-04-12
        • 2020-02-05
        • 1970-01-01
        • 2023-03-30
        • 2019-12-30
        • 2017-08-21
        相关资源
        最近更新 更多