[英]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.