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

Python 调用strip()后将split()转换为dict(),python,python-3.x,Python,Python 3.x,我想创建一个没有空格的split()序列产生的值字典 如果我有一个字符串列表,其格式如下: lines = ['Item1 = A Item2 = B Item3 = C', 'Item4 = D Item5 = E'] 我知道如何通过以下方式获得空白>2的配对: s=[y代表x中的x,y代表x中的y.split(“”),如果是y] 这将返回另一个包含以下对的字符串列表: s=['Item1=A','Item2=B','Item3=C'

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

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

lines = ['Item1 = A         Item2 = B         Item3 = C',
         'Item4 = D     Item5 = E']
我知道如何通过以下方式获得空白>2的配对:

s=[y代表x中的x,y代表x中的y.split(“”),如果是y]

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

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

到目前为止还不错。现在,我需要从这里用
=
来断开这些对,左边是
,右边是
。我可以通过以下方式做到这一点:

t=[y.split('=')代表x中的x行,y代表x中的y.split(''),如果是y]

这将返回另一个具有断开对的字符串列表:

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

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

t=[z.strip()表示x中的x行,表示x中的y.split(“”)表示y中的z.split(“”),如果y]

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

d=dict(y.split('=')表示x行中的x行,y表示x行中的y.split(''),如果y,则表示拆分('')

但这会使用
键和
值保留尾随或前导空格。如果我要添加
z.strip()
我会得到错误:

ValueError:字典更新序列元素#0的长度为5;2是必需的

问题:

如何同时使用
split('=')
调用中的
dict()
生成器和
strip()
空格?还是在调用
dict()
之后,我必须
strip()


您可以使用
2
步骤迭代
t

>>> 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'}
这个怎么样:

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'}

如果可以识别与正则表达式匹配的模式,那么可以使用
re
itertools
来处理
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'}
我的想法是:

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
生成对


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

您应该查看专用解析器,如
configparser
(标准库)或
pyparsing
(第三方)。您可以在
'='
上简单地
拆分
,而不是
'='
,以避免
剥离
。不要编辑带有答案的问题。答案属于答案。接受就足以表明问题已经解决。@AndrasDeak我编辑了一个更新的答案;我使用的解决方案与张贴的答案不一致。差异似乎是发布的一个很好的理由。在这种情况下,请在下面添加您自己的答案,即它所属的位置。使用
split
作为变量名会让人困惑。@Ev.Kounis是的,您可能是对的,我已经更改了它。非常好的解决方案!我只需要添加一个
.strip()
.rstrip()
来删除任何
'\n'
字符。找到了正确的解决方案序列。我已经更新了我的帖子。谢谢你的帮助!