这个列表理解+ product()组合

时间:2017-03-17 11:30:04

标签: python python-3.x

我有一个混合了字符串和列表的字典:

sample_dict = {'numbers': [1, 2, 3], 'ref': 'some text'}

目标是将它组合并“扁平化”为可迭代的单个词典,然后通过Celery将其用作一组计划任务的参数:

# end goal:
[{'numbers': 1, 'ref': 'some text'},
 {'numbers': 2, 'ref': 'some text'},
 {'numbers': 3, 'ref': 'some text'}]

我尝试使用传统的循环编写它以保持代码简单,以便以后适应或修正错误但我无法找到一种方法可以访问所有必要的嵌套变量。

结果是使用了一些相对复杂的列表推导:

raw_vals = [[(i,v)] if isinstance(v,str) else ([(i,b) for b in v]) for i,v in sample_dict.items()]
end_goal = [dict(i) for i in product(*raw_vals)]

因此问题:使用标准循环或类似方法,是否有更冗长但可能不那么神秘的方法来获得相同的结果?我知道这可能会引发关于可读性与LOC的争论,但如果可以的话,尽量忽略它。

2 个答案:

答案 0 :(得分:2)

我建议将第一个条件排除在外:

def assoc(i, v):
   if isinstance(v, list):
      return [(i, b) for b in v]
   return [(i, v)]

raw_vals = [assoc(i, v) for i, v in sample_dict.items())]
end_goal = [dict(i) for i in product(*raw_vals)]

然后理解就是地图。

我也可能建议测试值是否是列表而不是字符串,因为这将允许值为列表以外的任何类型而不是迭代。这也可以允许将列表的子类型视为列表。

答案 1 :(得分:0)

你的问题中缺少某些东西,或者你忽略了显而易见的事情:

>>> sample_dict = {'numbers': [1, 2, 3], 'ref': 'some text'}
>>> flattened = [{'numbers': num, 'ref': sample_dict['ref']} for num in      sample_dict['numbers']]
>>> print flattened
[{'ref': 'some text', 'numbers': 1}, {'ref': 'some text', 'numbers': 2}, {'ref': 'some text', 'numbers': 3}]