我有list
dict
。需要将其转换为list
namedtuple
(首选)或简单tuple
,同时按空格分割第一个变量。
什么是pythonic方式呢?
我简化了我的代码。欢迎使用理解,gen表达式和itertools。
数据中:
dl = [{'a': '1 2 3',
'd': '*',
'n': 'first'},
{'a': '4 5',
'd': '*', 'n':
'second'},
{'a': '6',
'd': '*',
'n': 'third'},
{'a': '7 8 9 10',
'd': '*',
'n': 'forth'}]
简单算法:
from collections import namedtuple
some = namedtuple('some', ['a', 'd', 'n'])
items = []
for m in dl:
a, d, n = m.values()
a = a.split()
items.append(some(a, d, n))
输出:
[some(a=['1', '2', '3'], d='*', n='first'),
some(a=['4', '5'], d='*', n='second'),
some(a=['6'], d='*', n='third'),
some(a=['7', '8', '9', '10'], d='*', n='forth')]
答案 0 :(得分:7)
下面,@ Petr Viktorin用我原来的答案和你的初步解决方案指出了问题:
警告!字典的values()没有任何特定的顺序!如果这个解决方案有效,并且a,d,n确实按顺序返回,那只是巧合。如果你使用不同版本的Python或以不同的方式创建dicts,它可能会破坏。
(我有点羞愧,我没有在第一时间拿到这个,并获得了45个代表!)
请改用@ eryksun的建议:
items = [some(m['a'].split(), m['d'], m['n']) for m in dl]
我原来的错误答案。除非您有OrderedDict
。
items = [some(a.split(), d, n) for a,d,n in (m.values() for m in dl)]
答案 1 :(得分:3)
以为我会在这里说话,因为我非常喜欢这个名字和词典!
这里有一个列表理解,其中有一个dict理解,可以对字典进行初始处理:
split_dictionaries = \
[{key: value.split() for k, value in d.iteritems()} for d in dl]
我经常使用我称之为“特百惠”的食谱,递归地将字典转换为命名元组。有关代码,请参阅the gist here。这是一个简化的部分,在这里集成,并有一个非常干净的方式来执行此操作。
import collections
def namedtuple_from_mapping(mapping, name="Tupperware"):
this_namedtuple_maker = collections.namedtuple(name, mapping.iterkeys())
return this_namedtuple_maker(**mapping)
所以给定这个函数,你可以这样做 - 我们很快就会重构:
split_namedtuples = [
namedtuple_from_mapping(
{key: value.split() for k, value in d.iteritems()}
) for d in dl
]
现在具有更好的封装和可读性:
def format_string(string):
return string.split()
def format_dict(d):
return {key: format_string(value) for key, value in d.iteritems()}
formatted_namedtuples = [namedtuple_from_mapping(format_dict(d)) for d in dl]
答案 2 :(得分:2)
另一种选择,不确定它是否比其他选择更好或更差:
class some(namedtuple('some', 'a d n')):
def __new__(cls, **args):
args['a'] = args['a'].split()
return super(some, cls).__new__(cls, **args)
items = list(some(**m) for m in dl)
BTW,我并非绝对致力于为基类提供与子类some
相同的名称。我喜欢它,因为它意味着生成的类使用名称some
转换为字符串,并且它从来没有特别引起我的问题,但如果您使用类名调试可能会令人困惑。所以要小心。
或使用不同技巧的相同想法:
some = namedtuple('some', 'a d n')
def make_some(args):
args = args.copy()
args['a'] = args['a'].split()
return some(**args)
items = map(make_some, dl) # NB: this doesn't return a list in Python 3
答案 3 :(得分:2)
另外@detly提供的答案,如果您事先不了解dicts的字段,可以使用
构建namedtuple
类
some = namedtuple('some', set(k for k in d.keys() for d in dl))