[英]Create a dictionary from list of tuples based on first element
我有一个看起来像这样的元组列表:
[('name', 'Name'),('name','Age'),('name','Hometown'),('value','Bob'),('value',27),('value','Chicago'),('name','Home Team'),('name','Away Team'),('name','Score'),('value','Broncos'),('value','Patriots'),('name','Month'),('value','January'),...]
本质上这是一堆桌子。 例如,第一个表将具有标题“姓名”、“年龄”和“家乡”,条目将是“鲍勃”、27 岁、“芝加哥”。
我试图把它变成这样的一本字典: {'Name':'Bob','Age':27,'Hometown':'Chicago, 'Home Team':'Broncos',...}
我相信我可以在正常情况下执行此操作,但是如果您查看第二个“表”,则有 3 个标题和只有 2 个值。 有没有办法将 map 在这种情况下将前两个“名称”转换为前两个“值”,将 map 第三个( 'Score'
)转换为空字符串?
ol = [('name', 'Name'),
('name','Age'),
('name','Hometown'),
('value','Bob'),
('value',27),
('value','Chicago'),
('name','Home Team'),
('name','Away Team'),
('name','Score'),
('value','Broncos'),
('value','Patriots'),
('name','Month'),
('value','January')]
l = ol.copy()
d = {}
noValue = False
while len(l) > 0 :
i = 1
while l[i][0] != 'value':
i += 1
d[l[0][1]] = l[i][1]
if i == 2 and l[i+1][0] == 'name':
d[l[1][1]] = ''
l = l[i + 1:]
else:
l = l[1:i] + l[i + 1:]
print(d)
印刷:
{'Name': 'Bob', 'Age': 27, 'Hometown': 'Chicago', 'Home Team': 'Broncos', 'Away Team': 'Patriots', 'Score': '', 'Month': 'January'}
只要仅缺少最后一个值,这应该可以工作。 此列表无效[('name','Home Team'), ('name','Away Team'), ('name','Score'), ('value','Broncos'), ('name','Month'), ('value','January')]
这是我提出的一个解决方案:
from itertools import zip_longest
tup = [('name', 'Name'),('name','Age'),('name','Hometown'),('value','Bob'),('value',27),('value','Chicago'),('name','Home Team'),('name','Away Team'),('value','Broncos'),('value','Patriots'),('name','Month'),('value','January'), ('name','Score')]
names = [item[1] for item in tup if item[0] == "name"]
values = [item[1] for item in tup if item[0] == "value"]
d = dict(zip_longest(names, values, fill_value=""))
Output:
{'Name': 'Bob', 'Age': 27, 'Hometown': 'Chicago', 'Home Team': 'Broncos', 'Away Team': 'Patriots', 'Month': 'January', 'Score': ''}
您可以使用标准zip()
function 但正如您所说,您需要 map 将多余的键转换为空字符串。 为此,请使用itertools.zip_longest
。 而且,请记住,在压缩两个可迭代对象时,顺序就是一切。 在您的问题中,元组("name", "Score")
出现在("name", "Month")
之前,最后一个 "value" 是("value", "January")
。 这将 map “分数”到一月而不是“月”。 因此,我在示例中更改了顺序。
希望这有帮助:)
我认为这行得通。 可能不是很漂亮,但如果你有几个缺失值的段,它应该是坚固的,并且不需要改变原始列表......虽然我刚刚学会了zip_longest
。 谢谢@Zunayn
一点点while循环结构可以解决这个问题:
data = [('name', 'Name'),('name','Age'),('name','Hometown'),('value','Bob'),('value',27),('value','Chicago'),
('name','Home Team'),('name','Away Team'),('name','Score'),('value','Broncos'),('value','Patriots'),('name','Month'),('value','January')]
# reverse the data for more efficient pop()
data = data[::-1]
results = {}
d = data.pop()
while data:
keys = []
while d[0] == 'name':
keys.append(d[1])
d = data.pop()
values = []
while d[0] == 'value':
values.append(d[1])
if data: # need to watch for end of list
d = data.pop()
else:
break
missing = len(keys) - len(values)
values.extend(['na']*missing)
# zip intermediate results and add to result
results.update({k:v for (k, v) in zip(keys, values)})
print(results)
产量:
{'Name': 'Bob', 'Age': 27, 'Hometown': 'Chicago', 'Home Team': 'Broncos', 'Away Team': 'Patriots', 'Score': 'na', 'Month': 'January'}
我只是建议,也许做这样的事情。 当然,如果您的名称和值按顺序存储,它将起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.