【问题标题】:How to create a dictionary from a list with a list of keys only and key-value pairs (Python)?如何从仅包含键列表和键值对(Python)的列表中创建字典?
【发布时间】:2016-10-08 21:00:23
【问题描述】:

这是这个问题的延伸:How to split a string within a list to create key-value pairs in Python

与上述问题的不同之处在于我的列表中的项目并非都是键值对;有些项目需要赋值。

我有一个清单:

list = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']

我想创建一个字典:

dict = { 'abc':'ddd', 'ef':1, 'ghj':1, 'jkl':'yui', 'rty':1 }

我的想法是这样的:

a = {}
for item in list:
   if '=' in item: 
     d = item.split('=')
     a.append(d) #I don't I can do this.
   else:
     a[item] = 1 #feel like I'm missing something here.

【问题讨论】:

  • 请附上您尝试过的代码及其存在的问题。
  • 您需要一些解析器逻辑,它会检测包含“=”的列表元素并将其拆分为键和值。

标签: python string list dictionary


【解决方案1】:

我将使用与您链接的帖子类似的内容。

d = dict(s.split('=') for s in a)

如果你结合从这篇文章中学到的东西——即使用列表创建字典——和使用if/else in Python's list comprehension,你可以想出这样的东西:

d = dict(s.split("=", maxsplit=1) if "=" in s else [s, 1] for s in l)

如果没有等号,则将1 添加到拆分列表的末尾。

【讨论】:

  • [s]+[1] 可以缩短为[s, 1]
  • 这是我书中真正的惊艳之处——一行并且完全可读。
  • 注意,如果s 中有两个或更多“=”,则会崩溃(引发 ValueError)。这可能是最好的选择。
  • 如果你想防崩溃,请使用s.split("=", maxsplit=1)。我不得不查一下。但是一想到需要,我就怀疑split方法一定是为它提供了,而且确实有。这就是我喜欢 Python 的原因。
【解决方案2】:
input_list = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']
output_dict = {}

for item in input_list:
    item_split = item.split('=')
    key = item_split[0]
    value = item_split[1] if len(item_split)>1 else 1
    output_dict[key] = value

简洁一点

for item in input_list:
    i_s = item.split('=')
    output_dict[i_s[0]] = i_s[1] if len(i_s)>1 else 1

这样做的好处是它不会将额外的元素附加到通过拆分 input_list 的元素创建的每个列表中。不过,列表推导可能比 for 循环更快

【讨论】:

  • 它可以更容易地完成,但我会等待代码尝试并首先遇到错误,然后再发布它。
【解决方案3】:

这里是一步一步的方法。

In [50]: mylist = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']

In [51]: [element.split('=') for element in mylist]
Out[51]: [['abc', 'ddd'], ['ef'], ['ghj'], ['jkl', 'yui'], ['rty']]

In [52]: [element.split('=') + [1] for element in mylist]
Out[52]: [['abc', 'ddd', 1], ['ef', 1], ['ghj', 1], ['jkl', 'yui', 1], ['rty', 1]]

In [53]: [(element.split('=') + [1])[:2] for element in mylist]
Out[53]: [['abc', 'ddd'], ['ef', 1], ['ghj', 1], ['jkl', 'yui'], ['rty', 1]]

In [54]: dict((element.split('=') + [1])[:2] for element in mylist)
Out[54]: {'abc': 'ddd', 'ef': 1, 'ghj': 1, 'jkl': 'yui', 'rty': 1}
  • 要将第 50 行中的列表转换为字典,您需要将其转换为第 53 行中的列表。
  • 第 51 行。第一步是用等号分割列表中的每个元素。现在,每个元素都转换为 1 或 2 个元素的列表。请注意,像 'ef' 这样没有等号的元素,我们必须修复它
  • 第 52 行。接下来,我们将 1 附加到每个子列表。这应该照顾具有 1 个元素的子列表,但使一些子列表 3 元素变长
  • 第 53 行:我们将所有子列表规范化为 2 元素的子列表,只取前两个元素并丢弃第三个元素(如果适用)。这个列表现在是正确的格式,可以转换成字典
  • 第 54 行。最后一步是获取此列表并将其转换为字典。由于dict 类可以采用生成器表达式,因此我们可以安全地删除方括号。

有了这个,这里是sn-p:

mylist = ['abc=ddd', 'ef', 'ghj', 'jkl=yui', 'rty']
mydict = dict((element.split('=') + [1])[:2] for element in mylist)

【讨论】:

    【解决方案4】:

    对于每个拆分“对”,您可以附加 [1] 并提取前 2 个元素。这样,当没有值时将使用 1:

    print dict((s.split('=')+[1])[:2] for s in l)
    

    【讨论】:

    • 这是一个惊人的。太棒了!
    • 感谢@fabricator!如果您不专门提取前两个元素[:2],可以解释为什么它不起作用?想确保我了解所有内容。
    • @AmeliaNchu,只是因为dict 方法需要它。来自documentationOtherwise, the positional argument must be an iterable object. Each item in the iterable must itself be an iterable with exactly two objects
    • 注意,如果 s 中有两个或更多“=”,则会静默失败。 (它会在第二个“=”处截断)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-14
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多