压缩两个长度为n和2n的数组以形成字典

时间:2019-01-08 13:56:25

标签: python

我正在为这个小事情而苦苦挣扎。假设:

field_name = ['name', 'age', 'sex']
field_values = ['john', '24', 'M', 'jane', '26', 'F']

输出类似:

{  'name': ['john','jane'],
   'age': ['24', '26'],
   'sex': ['M', 'F']
}

正在压缩:

dict_sample_fields = dict(zip(field_name, field_value))
#output
{  'name': 'john',
   'age': '24',
   'sex': 'M'
}

如何实现对值的循环压缩?

我可以实现具有多循环的这一长远目标。一线是很酷的:D。

8 个答案:

答案 0 :(得分:7)

真的很简单,您甚至不需要zip

{k: field_values[i::len(field_name)] for i, k in enumerate(field_name)}

# {'name': ['john', 'jane'], 'age': ['24', '26'], 'sex': ['M', 'F']}

利用切片list的步骤,并以field_name的索引开始。

答案 1 :(得分:4)

假设您的值之间相距3个索引,则可以执行此操作,而无需通过单个for循环使用任何zip。使用enumerate可以访问索引,您可以利用该索引访问列表值。如果您想使其更通用,则可以使用字段数(“键”)作为偏移量。

dict_sample_fields = {}

offset = len(field_name)

for i, key in enumerate(field_name):
    dict_sample_fields[key] = [field_values[i], field_values[i+offset]]

输出

{'name': ['john', 'jane'], 'age': ['24', '26'], 'sex': ['M', 'F']}

将它们放在一起

dict_sample_fields = {key: [field_values[i], field_values[i+3]] for i, key in enumerate(field_name)}

答案 2 :(得分:4)

我们可以使用grouper中的more_itertools函数或itertools文档中的同名recipe对值进行分组。然后可以用zip转置组。

>>> from more_itertools import grouper                                                                                            
>>>                                                                                                                               
>>> field_name = ['name', 'age', 'sex']                                                                                           
>>> field_values = ['john', '24', 'M', 'jane', '26', 'F']                                                                         
>>>                                                                                                                               
>>> dict(zip(field_name, map(list, zip(*grouper(len(field_name), field_values)))))                                                              
{'age': ['24', '26'], 'name': ['john', 'jane'], 'sex': ['M', 'F']}

这不会产生任何中间列表。

答案 3 :(得分:4)

假设您可以控制field_values的结构(据我的评论,您可以这样做),可以退后一步,然后将它们重新格式化到嵌套列表中。这样看起来会更好,可以更好地完成您的任务:

field_values = [['john', '24', 'M'], ['jane', '26', 'F']]

现在,它只是一条可读的行:

dict_sample_fields = dict(zip(field_name, zip(*field_values)))

产生:

{'name': ('john', 'jane'), 'age': ('24', '26'), 'sex': ('M', 'F')}

能够解决您遇到的任何问题绝对是一项非常重要的资产,但确保没有很多问题甚至更好。

答案 4 :(得分:3)

您可以多次使用zip

field_name = ['name', 'age', 'sex']
field_values = ['john', '24', 'M', 'jane', '26', 'F']

values = list(zip(*zip(field_values[::3],field_values[1::3], field_values[2::3])) )

result = { key : list(value) for key, value in zip(field_name, values)}
print(result)

输出

{'sex': ['M', 'F'], 'name': ['john', 'jane'], 'age': ['24', '26']}

或一行:

result = { key : list(value) for key, value in zip(field_name, zip(*zip(field_values[::3], field_values[1::3], field_values[2::3])))}

答案 5 :(得分:1)

这有很长的路要走。您可能可以为此编写单行代码,但会使它难以阅读。输出是不同的,但可能会帮助您解决问题。  希望对您有帮助

field_names = ['name', 'age', 'sex']
field_values = ['john', '24', 'M', 'jane', '26', 'F']

breaking_number = len(field_names)
master_dict = {}

# break list into equal parts size of field_names
chunks = [field_values[x:x+breaking_number] for x in range(0, len(field_values), breaking_number)]

for chunk in chunks:
    # zip this chunk with field_name and make one dict
    master_dict.update(list(zip(field_names, chunk)))
    print(master_dict)

输出:

{'name': 'john', 'age': '24', 'sex': 'M'}
{'name': 'jane', 'age': '26', 'sex': 'F'}

答案 6 :(得分:0)

这里是一个使用嵌套zip()的答案:

field_name = ['name', 'age', 'sex']
field_values = ['john', '24', 'M', 'jane', '26', 'F']

n = len(field_name)

result = dict(zip(field_name, map(list, zip(field_values[:n], field_values[n:]))))

print(result)
# {'name': ['john', 'jane'], 'age': ['24', '26'], 'sex': ['M', 'F']}

答案 7 :(得分:0)

这是解决问题的方法。

field_name = ['name', 'age', 'sex']
field_values = ['john', '24', 'M', 'jane', '26', 'F']

dict_vals = {}

for idx, filed in enumerate(field_name):
    dict_vals[filed] = field_values[idx::len(field_name)]

print(dict_vals)   
// {'age': ['24', '26'], 'name': ['john', 'jane'], 'sex': ['M', 'F']}

P.S:只是为了帮助您理解此声明field_values[idx::len(field_name)]

L[start_index::step_number]表示L的一部分,其中start_index是要开始的索引,step_number告诉解释器需要跳过多少个值索引。