繁体   English   中英

根据第一个元素从元组列表创建字典

[英]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'}

我只是建议,也许做这样的事情。 当然,如果您的名称和值按顺序存储,它将起作用。

  1. 从列表中提取键为“名称”的元组开始,如果出现“值”元组,则停止。
  2. 从该键创建字典,其中每个值都是暂时的空字符串。
  3. Go 返回列表并拉取值并按顺序设置到字典中。
  4. 如果出现另一个 'name' 元组,则 go 回到点 1。如果前一个字典中的某个键没有值,那么它将是空字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM