将列表解压缩为字符串,将其拆分并从中创建字典

时间:2018-08-10 14:45:43

标签: python python-3.x

我正在使用python 3.x,我想从列表中创建字典。也就是说,我将每个键和值连接在一个字符串中,并将每个条目作为列表中的一个元素。

my_list = ['val1 key1', 'val2 key2', 'val2 key2']

我可以使用

将其分为两个列表
values,keys = zip(*(s.split() for s in my_list))

从那里创建字典很容易。由于我仍然需要对键和值做一些事情,所以我这样做:

my_dict = {k[:-1]:float(v) for k,v in zip(keys,values)}

出于好奇,我想知道是否存在避免中间列表的方法。简而言之,我需要访问每个列表元素,拆分字符串,对每个拆分部分进行操作,然后将其作为key:value对输入到字典中。在我尝试了this个问题之后

my_dict = {k[:-1]:float(v) for v,k in zip(*(s.split() for s in my_list))}

但是我得到ValueError: too many values to unpack (expected 2)。然后,我尝试仅在字典理解语法中使用一个生成器(我认为它是一个生成器),并且可以正常工作。但我不喜欢它,因为第二个for仅用于从列表中提取元素:

my_dict = {s[1][:-1]:float(s[0]) for s in (s.split(', ') for s in my_list)}

这是我当前正在使用的并且可以正常使用,但是我想知道为什么第二个解决方案不起作用。对我来说,似乎应该,而且我的解决方案使用一对多的for。我知道这不是一个超级相关的问题,但我想学习。另外,我也乐意接受标题建议。

EDIT1:修复了我的一些语法错误。

EDIT2:如所建议的那样,具有预期结果的完整且明确的示例。我仍在努力改善mcve

my_list = ['1.123, name1\n', '2.3234, name2\n', '3.983, name3\n', '4.23, name4\n']

我想要的输出是手动完成后会得到的

my_dict = {'name1':1.123, 'name2':2.3234, 'name3':3.983, 'name4':4.23}

创建中间列表的方法:

values,keys = zip(*(s.split(', ') for s in my_list))
print(values)
>>> ('1.123', '2.3234', '3.983', '4.23')
print(keys)
>>> ('name1\n', 'name2\n', 'name3\n', 'name4\n')
my_dict = {k[:-1]:float(v) for k,v in zip(keys,values)}
print(my_dict)
>>> {'name4': 4.23, 'name2': 2.3234, 'name1': 1.123, 'name3': 3.983}

我不知道为什么它不起作用的示例:

my_dict = {k[:-1]:float(v) for v,k in zip(*(s.split(', ') for s in my_list))}
>>> ValueError: too many values to unpack (expected 2)

在我看来,它的工作示例似乎是在列表/字典理解/生成器表达式中使用for中的一个:

my_dict = {s[1][:-1]:float(s[0]) for s in (s.split(', ') for s in my_list)}
print(my_dict)
>>> {'name4': 4.23, 'name2': 2.3234, 'name1': 1.123, 'name3': 3.983}

我的实际字符串看起来像'0.9493432915614861, zf_AB012_bn_BOS\n' ,这就是为什么我使用一个更具可读性的示例。

EDIT3:我刚刚了解了str.strip()方法。这使创建字典的行变得更好:

my_dict = {s[1].strip():float(s[0]) for s in (s.split(', ') for s in my_list)}

2 个答案:

答案 0 :(得分:1)

def dict_unzip(lst):
    for x in lst:
        yield reversed(x.split(' ', 1))

my_dict = dict(dict_unzip(my_list))

但是由于它是Python3,所以实际上实际上要简单得多:

my_dict = dict(map(lambda s: reversed(s.split(' ', 1)), my_list))

甚至

my_dict = dict(reversed(s.split(' ', 1)) for s in my_list)

答案 1 :(得分:0)

您的开箱和打包操作没有达到预期的效果。建议您打印出结果(转换为list(...))以查看发生了什么。但是您不需要这样做,因为您已经有一个配对列表:

>>>my_list = ['3.2 key1', '1.1 key2', '5.4 key3']
>>>{k[-1]:float(v) for v,k in (a.split() for a in my_list)}
{'1': 3.2, '2': 1.1, '3': 5.4}

请注意,键在您的示例中是第二个,因此我将它们替换为。我也将:-1更改为-1以使我的示例正常工作,但由于您没有发布实际的内容,我猜测您需要:-1