【问题标题】:Trouble understanding how to use lambda to sort dict无法理解如何使用 lambda 对 dict 进行排序
【发布时间】:2023-04-07 00:53:01
【问题描述】:

我正在尝试对这本词典进行排序。

d = {'FNP': ['0.02', '0.02', '0.02', '0.02'],
     'TestName': ['Test1205', 'Test1206', 'Test1207', 'Test1208'],
     'eno': ['0', '0', '0', '0'],
     'GRE': ['0.00', '0.00', '0.00', '0.00'],
     'TPS': ['78.00', '45.00', '73400', '34.00'],
     'id': ['1', '1', '1', '1']}

我要做的是基于 TPS 排序并输出名称 wrt 排序值。这里 TPS[0] 对应于 TestTName[0]。我想在 TPS 排序时对 Testname 进行排序。 预期输出:

d = {'TestName': ['Test1208','Test1206','Test1205','Test1207'],
     'TPS':['34.00', '45.00', '78.00', '73400']

这是我目前所拥有的:sorted(d['TPS'],key=lambda d:d)

当我对TPS 进行排序时,如何确保Testnames 也可以互换?

【问题讨论】:

  • 那么您想对 Testname 和 TPS 的值进行排序吗?其他键发生了什么?
  • 我猜 73400 会出现在 78.00 之后。或者某处有错字。
  • d 不是 defaultdict(list),它只是一本普通的字典——所以请澄清你的问题。

标签: python sorting dictionary lambda


【解决方案1】:

这是一个实用的解决方案。诀窍是使用enumerate 提取索引,记住转换为float 进行排序,并使用带有多个参数的itemgetter 提取正确的顺序。

from operator import itemgetter

idx, _ = zip(*sorted(enumerate(d['TPS']), key=lambda x: float(x[1])))

res = {k: itemgetter(*idx)(d[k]) for k in ('TestName', 'TPS')}

{'TestName': ('Test1208', 'Test1206', 'Test1205', 'Test1207'),
 'TPS': ('34.00', '45.00', '78.00', '73400')}

【讨论】:

    【解决方案2】:

    除了@jpp 的解决方案之外,如果您想要在新字典中对原始字典中的所有列表进行排序版本,您可以使用原始 TPS 压缩每个数据列表,对元组进行排序并从中创建新数据列表排序后的数据:

    original_tps = [float(t) for t in d['TPS']]
    sorted_d = {}
    
    for k, v in d.items():
        sorted_d[k] = [x for tps, x in sorted([(t, e) for t, e in zip(original_tps, v)])]
    
    
    print(sorted_d['TPS'])
    # ['34.00', '45.00', '78.00', '73400']                                                                                                    
    print(sorted_d['TestName'])
    # ['Test1208', 'Test1206', 'Test1205', 'Test1207']
    # ... similarly other lists are sorted
    

    【讨论】:

      【解决方案3】:

      我会创建一个Record namedtuple 来保存每个单独的记录,然后轻松排序并在需要时强制返回到列表字典。

      from collections import namedtuple
      
      Record = namedtuple("Record", "FNP TestName eno GRE TPS id")
      
      def extract(d, keys=None):
          if keys is None:
              keys = ["FNP", "TestName", "eno", "GRE", "TPS", "id"]
          records = [Record(*vals) for vals in zip(*map(d.get, keys))]
          return records
      
      def transform(records):
          records.sort(key=lambda r: float(r.TPS))
      
      def load(records, keys=None):
          if keys is None:
              keys = ["FNP", "TestName", "eno", "GRE", "TPS", "id"]
          d = {k: [getattr(record, k) for record in records] for k in keys}
          return d
      
      d = {'FNP': ['0.02', '0.02', '0.02', '0.02'],
           'TestName': ['Test1205', 'Test1206', 'Test1207', 'Test1208'],
           'eno': ['0', '0', '0', '0'],
           'GRE': ['0.00', '0.00', '0.00', '0.00'],
           'TPS': ['78.00', '45.00', '73400', '34.00'],
           'id': ['1', '1', '1', '1']}
      records = extract(d)
      transform(records)
      new_d = load(records)
      

      【讨论】:

        【解决方案4】:

        假设您希望TPS 列表按数字 排序,而不是按词法(按其中每个字符串元素的值按字母顺序排列):

        from pprint import pprint
        
        d = {'FNP': ['0.02', '0.02', '0.02', '0.02'],
             'TestName': ['Test1205', 'Test1206', 'Test1207', 'Test1208'],
             'eno': ['0', '0', '0', '0'],
             'GRE': ['0.00', '0.00', '0.00', '0.00'],
             'TPS': ['78.00', '45.00', '73400', '34.00'],
             'id': ['1', '1', '1', '1']}
        
        d['TestName'] = sorted(d['TestName'])
        d['TPS'] = sorted(d['TPS'], key=float)
        
        pprint(d)
        

        输出:

        {'FNP': ['0.02', '0.02', '0.02', '0.02'],
         'GRE': ['0.00', '0.00', '0.00', '0.00'],
         'TPS': ['34.00', '45.00', '78.00', '73400'],
         'TestName': ['Test1205', 'Test1206', 'Test1207', 'Test1208'],
         'eno': ['0', '0', '0', '0'],
         'id': ['1', '1', '1', '1']}
        

        请注意,TestName 列表已经排序。

        【讨论】:

        • 这里根本不需要 lambda:d['TPS'] = sorted(d['TPS'], key=lambda value: float(value))。你可以这样写:d['TPS'] = sorted(d['TPS'], key=float)
        • @hughdbrown:非常正确...答案已更新。感谢您指出。
        猜你喜欢
        • 1970-01-01
        • 2019-11-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-20
        • 2011-08-09
        • 1970-01-01
        相关资源
        最近更新 更多