调用strip()后将split()转换为dict()

时间:2017-08-07 12:45:57

标签: python python-3.x

我想创建一个由没有空格的split()序列产生的值字典。

如果我有一个格式如下的字符串列表:

lines = ['Item1 = A         Item2 = B         Item3 = C',
         'Item4 = D     Item5 = E']

我知道如何通过空格> 2获取

s = [y for x in lines for y in x.split(' ') if y]

这将返回另一个包含的字符串列表:

s = ['Item1 = A', 'Item2 = B', 'Item3 = C', 'Item4 = D', 'Item5 = E']

到目前为止一切顺利。现在,我需要在=之前打破,左侧是key,右侧是value。我可以通过以下方式做到这一点:

t = [y.split('=') for x in lines for y in x.split(' ') if y]

这将返回另一个包含损坏对的字符串列表:

t = ['Item1 ', ' A', 'Item2 ', ' B', 'Item3 ', ' C', 'Item4 ', 'D', 'Item5 ', ' E']

现在每个项目都有一个尾部或前导空格。通过将最后一个列表理解行更新为:

,可以轻松解决此问题

t = [z.strip() for x in lines for y in x.split(' ') for z in y.split('=') if y]

为了使这个字典我知道调用生成器表达式:

d = dict(y.split('=') for x in lines for y in x.split(' ') if y)

但是这会使keyvalue保留尾随或前导空格。如果我要添加z.strip(),我会收到错误:

ValueError: dictionary update sequence element #0 has length 5; 2 is required

问题:

  

如何同时使用dict()电话中的strip()生成器和split('=')空格?或者我在strip()电话后被迫dict()

4 个答案:

答案 0 :(得分:3)

这个怎么样:

s = ['Item1 = A', 'Item2 = B', 'Item3 = C', 'Item4 = D', 'Item5 = E']

#b = dict([x.split(' = ') for x in s])  # list comprehension: slightly faster.
b = dict(x.split(' = ') for x in s)     # generator expr.   : memory efficient.

print(b)  # {'Item3': 'C', 'Item1': 'A', 'Item4': 'D', 'Item5': 'E', 'Item2': 'B'}

答案 1 :(得分:0)

您可以使用ranget的步骤迭代2

>>> t = [z.strip() for x in lines for y in x.split('  ') for z in y.split('=') if y]
>>> t
['Item1', 'A', 'Item2', 'B', 'Item3', 'C', 'Item4', 'D', 'Item5', 'E']

>>> dict((t[i], t[i + 1]) for i in range(0, len(t), 2))
{'Item2': 'B', 'Item3': 'C', 'Item1': 'A', 'Item4': 'D', 'Item5': 'E'}

要将它们全部放在一行中你还可以写:

>>> d = dict(tuple(k.strip() for k in y.split('=')) for x in lines for y in x.split('  ') if y)

>>> d
{'Item2': 'B', 'Item3': 'C', 'Item1': 'A', 'Item4': 'D', 'Item5': 'E'}

答案 2 :(得分:0)

如果您可以识别与正则表达式匹配的模式,那么您可以使用reitertools来处理dict创建

>>> import itertools
>>> import re
>>> dict(itertools.chain.from_iterable(re.findall('(\w+\d+) = (\w+)', line) for line in lines))
{'Item1': 'A', 'Item2': 'B', 'Item4': 'D', 'Item3': 'C', 'Item5': 'E'}

答案 3 :(得分:0)

这是我的理由:

lines = ['Item1 = A         Item2 = B         Item3 = C',
         'Item4 = D     Item5 = E']
gen = (piece for line in lines for piece in line.split() if piece != '=')
d = dict(zip(gen, gen))
print(d)
>>> {'Item4': 'D', 'Item2': 'B', 'Item1': 'A', 'Item3': 'C', 'Item5': 'E'}

或者如果你想把事情塞进一行:

d = dict(zip(*[(p for l in lines for p in l.split() if p != '=')] * 2))

不是通过双空格然后通过等于分割,而是通过一般的空格分割,然后删除等于标记。然后将生成器传递两次到zip以生成dict的对。

这种解决方案的缺点是它需要在等号周围始终有空格。