【问题标题】:Sort a dictionary by list of lists [duplicate]按列表列表对字典进行排序[重复]
【发布时间】:2014-01-30 05:55:55
【问题描述】:

我正在尝试按列表对字典进行排序。列表列表中的项目是字典中的键。我之前问过,但答案并没有解决问题。

我的输入列表是:

   mylist= [
    ['why', 'was', 'cinderella', 'late', 'for', 'the', 'ball', 'she', 'forgot', 'to', 'swing', 'the', 'bat'],
    ['why', 'is', 'the', 'little', 'duck', 'always', 'so', 'sad', 'because', 'he', 'always', 'sees', 'a', 'bill', 'in', 'front', 'of', 'his', 'face'],
    ['what', 'has', 'four', 'legs', 'and', 'goes', 'booo', 'a', 'cow', 'with', 'a', 'cold'], 
    ['what', 'is', 'a', 'caterpillar', 'afraid', 'of', 'a', 'dogerpillar'],
    ['what', 'did', 'the', 'crop', 'say', 'to', 'the', 'farmer', 'why', 'are', 'you', 'always', 'picking', 'on', 'me']
    ]

我的字典有点像这样:

    myDict = {'to': [7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56], 
    'jam': [20], 'black': [5], 'farmer': [11],
    'woodchuck': [54], 'has': [14, 16, 51], 'who': [16]
    }

我的代码是:

    def sort_by_increasing_order(mylist, myDict):
    #temp = sorted(myDict, key=myDict.get)
    temp = sorted(myDict, key=lambda tempKey: for tempKey in mylist, reverse=True )
    return temp

类似:

    sort_by_increasing_order(['d', 'e', 'f'], {'d': [0, 1], 'e': [1, 2, 3], 'f': [4]})
    result: ['f', 'e', 'd']

所以对于我的示例输入,它看起来像:

        sort_by_increasing_order(mylist, myDict)
        >> ['to','woodchuck','has','jam','who','farmer']

当我尝试按列表排序时,注释行仅按字典键排序。我的做法不正确。结果应该是一个按上述索引长度递增顺序的列表。任何建议。

【问题讨论】:

  • 您将如何比较密钥?
  • 您不能按键对字典进行排序。根据定义,字典没有排序。

标签: python sorting dictionary


【解决方案1】:

参考@doukremt的回答 假设你知道装饰器。

mydict = {'d': [0, 1], 'e': [1, 2, 3], 'f': [4]}
mylist = [['d', 'e', 'f', 'c'], ['c', 'v', 'd', 'n']]

def convert_to_set(mylist, result_set=None):
    if result_set is None:
        result_set = []
    for item in mylist:
        if isinstance(item, str):
            result_set.append(item)
        if isinstance(item, list):
            convert_to_set(item, result_set)
    return set(result_set)

def list_to_set(f):
    def wrapper(mylist, mydict):
        myset = convert_to_set(mylist)
        result = f(myset, mydict)
        return result
    return wrapper

@list_to_set
def findit(mylist, mydict):
    gen = ((k, mydict[k]) for k in mylist if k in mydict)
    return [k for k, v in sorted(gen, key=lambda p: len(p[1]))]

print findit(mylist, mydict)

【讨论】:

  • 非常感谢您的回答。让我试试看。对不起,我不知道装饰器。如果你能解释你的代码在做什么,那就太好了。
  • 谢谢。让我试试看。
  • 能否请您解释一下流程等,这会有所帮助。我无法理解。谢谢
  • 好的。我已将嵌套列表转换为设置。这样列表和子列表中的所有关键字都将在集合内(不重复)。装饰器只是将您的嵌套列表参数(mylist)转换为设置。现在,findit 将在原始 mylist 的集合上运行。简而言之 [['d', 'e', 'f', 'c'], ['c', 'v', 'd', 'n']] => {'d', 'e', 'c'、'v'、'f'、'n'}
【解决方案2】:
def findit(mylist, mydict):
    gen = ((k, mydict[k]) for k in mylist if k in mydict)
    return [k for k, v in sorted(gen, key=lambda p: len(p[1]))]


>>> findit(['d', 'e', 'f'], {'d': [0, 1], 'e': [1, 2, 3], 'f': [4]})
['f', 'd', 'e']

【讨论】:

  • 感谢您的回答。但我得到 TypeError: unhashable type: 'list'。如果你是在单个列表上做的,而我在上面发布了列表列表。
  • @user3247054:那么您必须将嵌套列表转换为元组,或者使用不同的数据结构。您无法在字典中搜索列表
  • 如果我理解正确,您有列表关键字列表,关键字可以出现在任何子列表中。因此,我建议将列表列表转换为单个集合,以便它将所有关键字作为字符串包含并使用上面的代码。列表不可散列,因此不能用作字典键。
  • @doukremt 如果要返回索引。代码会有什么变化?
  • 没关系。
【解决方案3】:
>>> D= {'to': [7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56], 
...     'jam': [20], 'black': [5], 'farmer': [11],
...     'woodchuck': [54], 'has': [14, 16, 51], 'who': [16]
...     }
>>> 
>>> sorted(D, key=lambda k:len(D[k]), reverse=True)
['to', 'has', 'who', 'jam', 'black', 'farmer', 'woodchuck']

对于价值观

>>> sorted(D.values(), key=len, reverse=True)
[[7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56], [14, 16, 51], [16], [20], [5], [11], [54]]

对于(键、值)

>>> sorted(D.items(), key=lambda i:len(i[1]), reverse=True)
[('to', [7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56]), ('has', [14, 16, 51]), ('who', [16]), ('jam', [20]), ('black', [5]), ('farmer', [11]), ('woodchuck', [54])]

编辑: 仍然不太清楚您的要求。您的示例似乎根本不关心长度,否则“有”应该在“土拨鼠”之前?将len 更改为max 可能是您想要的

>>> D = {'to': [7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56], 
...     'jam': [20], 'black': [5], 'farmer': [11],
...     'woodchuck': [54], 'has': [14, 16, 51], 'who': [16]
...     }
>>> 
>>> sorted(D, key=lambda k:max(D[k]), reverse=True)
['to', 'woodchuck', 'has', 'jam', 'who', 'farmer', 'black']
>>> sorted(D.values(), key=max, reverse=True)
[[7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56], [54], [14, 16, 51], [20], [16], [11], [5]]
>>> sorted(D.items(), key=lambda i:max(i[1]), reverse=True)
[('to', [7, 11, 17, 23, 24, 25, 26, 33, 34, 37, 39, 41, 47, 48, 53, 56]), ('woodchuck', [54]), ('has', [14, 16, 51]), ('jam', [20]), ('who', [16]), ('farmer', [11]), ('black', [5])]

【讨论】:

  • 感谢您的回答。这将返回密钥。如果我想返回值怎么办?
  • 非常感谢。但它没有对列表列表进行排序?
  • 对不起,我不明白你在问什么(也许这里没有人知道)。你能用一个恰当的例子来澄清你的问题吗?
  • 我已经更新了。如果您现在清楚这一点,请告诉我。
  • @user3247054,我已经更新了我的答案。我不明白长度是怎么来的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-04
  • 2016-12-11
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
相关资源
最近更新 更多