Python - 将dict的某些字段转换为列表

问题描述 投票:0回答:3

我有以下Python dict:

{
  'parameter_010': False, 
  'parameter_009': False, 
  'parameter_008': False, 
  'parameter_005': 'C<sub>MAX</sub>', 
  'parameter_004': 'L', 
  'parameter_007': False, 
  'parameter_006': 'R', 
  'parameter_001': 'Foo', 
  'id': 7542, 
  'parameter_003': 'D', 
  'parameter_002': 'M'
}

如图所示,有许多名为parameter_nnn的字段,其中nnn是一个序列号。有些是False,其他人有值。

我想生成一个只包含parameter_nnn字段值的列表,但只包含包含给定值的列表,按001向上的数字排序。

因此,在这种特定情况下,所需的输出是:

["Foo", "M", "D", "L", "CMAX", "R"]

这样做的pythonic方式是什么?我显然可以开始迭代,但想知道是否有更好的东西。

Python 2.7

python python-2.7
3个回答
2
投票

因此,假设您知道您正在使用JSON以及如何反序列化:

>>> import json
>>> s = """{
...   "parameter_010": false,
...   "parameter_009": false,
...   "parameter_008": false,
...   "parameter_005": "CMAX",
...   "parameter_004": "L",
...   "parameter_007": false,
...   "parameter_006": "R",
...   "parameter_001": "Foo",
...   "id": 7542,
...   "parameter_003": "D",
...   "parameter_002": "M"
... }"""
>>> d = json.loads(s)

如果您的parameter_nnn始终并严格遵循此格式,您可以简单地按您的要求筛选过滤的项目(因为词典排序是您想要的!):

>>> sorted([(k,v) for k, v in d.items() if v and k.startswith('parameter')])
[('parameter_001', 'Foo'), ('parameter_002', 'M'), ('parameter_003', 'D'), ('parameter_004', 'L'), ('parameter_005', 'CMAX'), ('parameter_006', 'R')]

如果您只想要这些值,只需再做一遍:

>>> [v for _,v in sorted([(k,v) for k, v in d.items() if v and k.startswith('parameter')])]
['Foo', 'M', 'D', 'L', 'CMAX', 'R']
>>>

注意,你将不得不以某种方式循环...

更易读的版本:

>>> selection = [(k,v) for k, v in d.items() if v and k.startswith('parameter')]
>>> [v for _,v in sorted(selection)]
['Foo', 'M', 'D', 'L', 'CMAX', 'R']

EDIT: Major Caveat

请注意,如果值可以是0或您实际需要的任何其他虚假值,那么这将不起作用,例如:

>>> pprint(d)
{'id': 7542,
 'parameter_001': 'Foo',
 'parameter_002': 'M',
 'parameter_003': 'D',
 'parameter_004': 'L',
 'parameter_005': 'CMAX',
 'parameter_006': 'R',
 'parameter_007': False,
 'parameter_008': False,
 'parameter_009': False,
 'parameter_010': False,
 'parameter_011': 0}
>>> selection = [(k,v) for k, v in d.items() if v and k.startswith('parameter')]
>>> [v for _, v in sorted(selection)]
['Foo', 'M', 'D', 'L', 'CMAX', 'R']

因此,如果你想特别过滤False的实例(而不是0),那么你必须使用is

>>> selection = [(k,v) for k, v in d.items() if v is not False and k.startswith('parameter')]
>>> [v for _, v in sorted(selection)]
['Foo', 'M', 'D', 'L', 'CMAX', 'R', 0]

0
投票

这是一个解决方案:

list(zip(*sorted(i for i in d.items() if i[0].startswith('parameter') and i[1])))[1]

# ('Foo', 'M', 'D', 'L', 'C<sub>MAX</sub>', 'R')

说明

  • 我们过滤了2个条件:键以'参数'开头,值为Truthy。
  • sorted上的d.items()返回按字典键排序的元组列表。
  • list(zip(*..))[0]在上一次过滤和排序后返回一个值元组。
  • 我没有处理<sub></sub>,因为我不知道它来自何处以及应该采用什么逻辑来删除这个(以及其他?)标记。

0
投票
import collections

dicty = {
  "parameter_010": False, 
  "parameter_009": False, 
  "parameter_008": False, 
  "parameter_005": "CMAX", 
  "parameter_004": "L", 
  "parameter_007": False, 
  "parameter_006": "R", 
  "parameter_001": "Foo", 
  "id": 7542, 
  "parameter_003": "D", 
  "parameter_002": "M"
}
result = []

od = collections.OrderedDict(sorted(dicty.items()))
for k, v in od.iteritems():
    if v != False and "parameter" in k:
        result.append(v)
print(result)
© www.soinside.com 2019 - 2024. All rights reserved.