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

时间:2018-03-01 22:07:45

标签: python python-2.7

我有以下Python词典:

{
  '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

3 个答案:

答案 0 :(得分: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']

编辑: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]

答案 1 :(得分: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个条件:密钥以&#39;参数&#39;和价值是Truthy。
  • sorted上的
  • d.items()返回按字典键排序的元组列表。
  • list(zip(*..))[0]在上一次过滤和排序后返回一个值元组。
  • 我还没有处理<sub></sub>,因为我不知道它来自何处以及应该采用什么逻辑来删除此(和其他?)标记。

答案 2 :(得分: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)