以下是将用于创建字典的键。
keys = ['a', 'b','c']
添加挑战的是列表中包含不同嵌套级别的值列表,这些列表需要展平,但前提是它只有一个项目。例如,[3,3,5]
不应该被展平,因为它代表一个群组。
values = [
[[1],[1],[1]],
[[1],[0],1],
[2,0,[3,3,5]],
[1,[[1]],0]
]
我尝试了print dict(zip(key_list, cols))
,但这似乎并没有产生预期的输出:
[{'a':1, 'b':1, 'c':1} , {'a':1, 'b':0, 'c':1}, {'a':2, 'b':0, 'c':[3,3,5]}]
答案 0 :(得分:2)
根据您的输入和预期输出,您可以通过使用循环来克服单个嵌套挑战。 该程序可以写成
values = [
[[1],[1],[1]],
[[1],[0],1],
[2,0,[3,3,5]],
[1,[[1]],0]
]
keys = ['a','b','c']
l = []
for i in values:
d = dict()
for j in range(3):
ele = i[j]
while isinstance(ele,list) and len(ele) == 1:
ele = ele[0]
else:
d[keys[j]] = ele
l.append(d)
print (l)
输出
[{'a': 1, 'b': 1, 'c': 1}, {'a': 1, 'b': 0, 'c': 1}, {'a': 2, 'b': 0, 'c': [3, 3, 5]}, {'a': 1, 'b': 1, 'c': 0}]
正如所料。 (但是当字典被散列时,顺序会有所不同)
注意 - 我使用 SHORT CIRCUIT EVALUATION 来防止使用多个条件语句
答案 1 :(得分:1)
由于深度嵌套,您需要递归或迭代地展平单个元素列表。我根据您的规范使用get_flat
来完成它。
#!/usr/bin/env python
# flatten single element lists recursively.
# using a while loop is probably better
def get_flat(elem):
if isinstance(elem, list):
if len(elem) > 1:
return elem
else:
return get_flat(elem[0])
return elem
values = [
[[1],[1],[1]],
[[1],[0],1],
[2,0,[3,3,5]],
[1,[[1]],0]
]
keys = ['a','b', 'c']
# zip keys and values for each flat column (uses get_flat to flatten)
# and convert to dict
print map(dict, map(lambda col: zip(keys, map(get_flat, col)), values))
输出:
[{'a': 1, 'c': 1, 'b': 1}, {'a': 1, 'c': 1, 'b': 0}, {'a': 2, 'c': [3, 3, 5], 'b': 0}, {'a': 1, 'c': 0, 'b': 1}]
答案 2 :(得分:0)
首先你需要平衡你的值,你可以使用以下递归函数来完成:
>>> def flat(l):
... if not any(isinstance(i,list) and len(i)==1 for v in l for i in v):
... return l
... else :
... return flat([[i[0] if isinstance(i,list) and len(i)==1 else i for i in v] for v in l])
...
>>> flat(values)
[[1, 1, 1], [1, 0, 1], [2, 0, [3, 3, 5]], [1, 1, 0]]
然后使用以下列表理解:
>>> [dict(zip(keys,l)) for l in flat(values)]
[{'a': 1, 'c': 1, 'b': 1}, {'a': 1, 'c': 1, 'b': 0}, {'a': 2, 'c': [3, 3, 5], 'b': 0}, {'a': 1, 'c': 0, 'b': 1}]
但是这给了你一个包含4个项目的词典列表,你想要3,意味着你想要[1, 0, 1]
和[1, 1, 0]
的一个词典,因此你需要删除其中一个你能做到的排序它们和列表理解:
>>> p=[sorted(i) for i in flat(values)]
>>> [j for i,j in enumerate(p) if p[i+1:].count(j)<1]
[[1, 1, 1], [0, 2, [3, 3, 5]], [0, 1, 1]]
>>> [dict(zip(keys,l)) for l in last_l]
[{'a': 1, 'c': 1, 'b': 1}, {'a': 0, 'c': [3, 3, 5], 'b': 2}, {'a': 0, 'c': 1, 'b': 1}]
答案 3 :(得分:0)
你可以写一个递归函数,它可以根据你拥有的嵌套列表的级别来展平你的列表。
与您的情况类似,[[1]]
def get_values(values,count):
for i in range(count):
count = count - 1
values = [[each[0] if isinstance(each, list) and len(each) ==1 else each for each in val] for val in values]
return get_values(values,count)
else:
return values
keys = ['a', 'b','c']
values = [
[[1],[1],[1]],
[[1],[0],1],
[2,0,[3,3,5]],
[1,[[1]],0]
]
count = max([str(each).count('[') for row in values for each in row if isinstance(each, list)])
# count = 2
print [dict(zip(keys, each)) for each in get_values(values, count)]
结果:
[{'a': 1, 'c': 1, 'b': 1}, {'a': 1, 'c': 1, 'b': 0},
{'a': 2, 'c': [3, 3, 5], 'b': 0}, {'a': 1, 'c': 0, 'b': 1}]
如果最大嵌套级别为3,则只需将3作为参数传递给递归函数。
例如,此处值为元素[[[1]]]
的最大嵌套级别为3,因此我们只需传递3作为get_values
函数的计数参数值:
keys = ['a', 'b','c']
values = [
[[1],[1],[1]],
[[1],[0],1],
[2,0,[3,3,5]],
[1,[[[1]]],0]
]
count = max([str(each).count('[') for row in values for each in row if isinstance(each, list)])
# count = 3
print [dict(zip(keys, each)) for each in get_values(values, count)]
结果:
[{'a': 1, 'c': 1, 'b': 1}, {'a': 1, 'c': 1, 'b': 0},
{'a': 2, 'c': [3, 3, 5], 'b': 0}, {'a': 1, 'c': 0, 'b': 1}]
答案 4 :(得分:-1)
我假设你的最后一句话意味着 [{'a':1,'b':1,'c':1},{'a':1,'b':0,'c':1},{'a':2,'b ':0,'c':[3,3,5]}] 是你的预期产量。
然后
keys = ['a', 'b', 'c']
values = [
[[1],[1],[1]],
[[1],[0],1],
[2,0,[3,3,5]],
[1,[[1]],0]
]
print [dict(zip(keys, entry)) for entry in values]
是您想要的结果。
[{'a': [1], 'b': [1], 'c': [1]}, {'a': [1], 'b': [0], 'c': 1}, {'a': 2, 'b': 0, 'c': [3, 3, 5]}, {'a': 1, 'b': [[1]], 'c': 0}]
你的问题是zip(键,值)将构成值的每个列表视为键指向的值。所以你得到了
{'a': [[1], [1], [1]], 'c': [2, 0, [3, 3, 5]], 'b': [[1], [0], 1]}