【问题标题】:Read string variables into variables [closed]将字符串变量读入变量[关闭]
【发布时间】:2015-05-22 09:43:54
【问题描述】:

我想将三个关键字 %vel%note%blah 从字符串解析为整数:

s = "%vel=127, %note=64,     %blah=13"

# should give { 'vel': 127, 'note': 64,  'blah': 13}
# or vel = 127 // note = 64 //  blah = 13

s = "%blah=5,%note=44"
# should give { 'blah': 5, 'note': 44} 

我做过类似的事情:

s = "%vel=127, %note=64,     %blah=13"
d = dict()
for k in s.split(','):
    k = k.strip()
    if "%vel" in k: d['vel'] = int(k.split("%vel=")[1])
    if "%note" in k: d['note'] = int(k.split("%note=")[1])
    if "%blah" in k: d['blah'] = int(k.split("%blah=")[1])
print d

它有效,但我觉得它很丑。

如何以更好/pythonic 的方式做到这一点?

【问题讨论】:

  • 使用正则表达式组
  • 我已将此标记为“更好”是基于意见的。让您的问题更具体。
  • @HiteshDharamdasani:你有例子吗?它会比当前代码更短吗?
  • 您正在寻找的是“如何摆脱那些ifs 和“魔法”字符串?”
  • @khajvah 你是对的:我的意思是我正在寻找一种对边缘情况更健壮的解决方案,寻找更自然的东西来完成这些工作,例如内置模块这可能吗?

标签: python pattern-matching


【解决方案1】:

真正快速的列表理解示例:

s = "%blah=5, %note=44"
print dict([item.split('=') for item in s.replace(' ','').replace('%', '').split(',')])

编辑:

s = "%blah=5, %note=44"
# existing dict
old_dict_with_data = { ... }     
result = dict(map(lambda x: [x[0], int(x[1])], [item.split('=') for item in s.replace(' ', '').replace('%', '').split(',')]))
old_dict_with_data.update(result)

我建议将这些理解内容拆分为几个操作,因为我承认它看起来不太可读:(

请随意填写,我会解释的

【讨论】:

  • 太棒了!如果我们假设 dict 之前已经创建过,并且其中包含一些其他值,我们可以修改您的代码以更新 dict 吗?
  • 超级!一个小问题:为什么.replace(' ', '') 有效但.strip() 无效(我试过)
  • 我还添加了将所有值转换为 int 的修复程序。
  • 因为 strip 只删除字符串开头和结尾的空格
  • 我可能会使用你以前的版本:print dict([item.split('=') for item in s.replace(' ','').replace('%', '').split(',')])
【解决方案2】:

这很容易用正则表达式:

示例:

>>> from re import findall
>>> s = "%vel=127, %note=64,     %blah=13"
>>> m = findall("%([a-z]+)=([0-9]+)", s)
>>> d = dict(m)
>>> d
{'note': '64', 'blah': '13', 'vel': '127'}

您甚至可以将整数值转换为正确的int(s):

>>> dict((k, int(v)) for k, v in m)
{'note': 64, 'blah': 13, 'vel': 127}

【讨论】:

  • 它实际上看起来不像我的解决方案那么可怕。不错!
  • 正则表达式和一些函数式编程没有任何问题。提供了一个非常易读的解决方案。
  • 不错的解决方案@JamesMills!
【解决方案3】:

不知道为什么没人做字典理解。

>>> s = "%blah=5, %note=44"
>>> {k: int(v) for k, v in (item[1:].split('=') for item in s.split(', '))}
{'note': 44, 'blah': 5}

编辑:对于格式错误的情况:

>>> s = "%vel=127, %note=64,     %blah=13"
>>> {k: int(v) for k, v in (item.strip()[1:].split('=') for item in s.split(','))}
{'vel': 127, 'note': 64, 'blah': 13}

【讨论】:

  • s = "%vel=127, %note=64, %blah=13" 为此,您需要去除空格,否则您会得到类似 {' %blah': 13, '注意':64,'vel':127}
  • @Ajay 谢谢,已修复。这就是我从接受的答案中复制示例所得到的:-P
【解决方案4】:

为什么不使用列表推导?

key_val_list = [k.strip().split('=') for k in s.split(',')]
for item in key_val_list:
    d[item[0][1:]] = int(item[1])

【讨论】:

  • 你去!我不明白为什么人们投票反对。我没有时间详细说明,因此被淘汰了:(
  • 我现在投了赞成票!我认为他们投了反对票,因为他们认为您的第一个答案版本更像是评论而不是答案
  • 谢谢。我很感激
【解决方案5】:
In [101]: dict(map(lambda v: v.replace('%','').split('='), map(str.strip, s.split(','))))
Out[101]: {'blah': '13', 'note': '64', 'vel': '127'}

如果您的 dict 已经存在,只需将结果分配给该变量即可。

【讨论】:

    猜你喜欢
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 2017-03-18
    • 2010-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    相关资源
    最近更新 更多