【问题标题】:Is there a way to unpack the result of split() inside of for-loop?有没有办法在 for 循环中解压 split() 的结果?
【发布时间】:2021-08-30 11:52:51
【问题描述】:

我知道问题的标题可能不是最直观的,但我想不出更好的方式来简短地描述它,这就是我的真正意思。

我想写一些小的解析器,它会用我指定的字符串构建一个 kwargs 字典。

这是一个例子:

string_of_kwargs = 'n=6,m=10'
graph_kwargs = {pair.split('=')[0]:pair.split('=')[1]
                    for pair in string_of_kwargs.split(',')}

输出是:

{'n': '6', 'm': '10'}

问题是在上面的代码中我不得不使用 pair.split('=') 两次 我想知道是否有办法绕过它,以防我将来不得不解压缩更多这样的值。

【问题讨论】:

标签: python loops dictionary keyword-argument unpack


【解决方案1】:

当然:

>>> dict(pair.split('=', 1) for pair in string_of_kwargs.split(','))
{'n': '6', 'm': '10'}

为什么1 作为split() 的第二个参数?以防万一有多个'=' 符号。不过,要做到这一点,还有更多工作要做,但这超出了问题的范围。

【讨论】:

    【解决方案2】:

    您可以通过像这样遍历单个元素列表来巧妙地​​使用嵌套的 for 子句来绑定到名称:

    graph_kwargs = {
        k:v for pair in string_of_kwargs.split(',')
        for k,v in [pair.split('=')]
    }
    

    注意,我称之为 hackey,但它显然是惯用的,值得在 Python 3.9 中进行定制优化,它基本上被编译为常规分配,而不是实际创建中间列表。您可以通过使用dis 不同版本的解释器来亲眼看到这一点。

    【讨论】:

    • 谢谢,这个技巧似乎更通用了。
    【解决方案3】:

    另一种选择(尽管我仍然推荐using dict and a generator):

    >>> from operator import methodcaller
    >>> kv_split = methodcaller('split', '=', 1)
    >>> {k: v for k, v in map(kv_split, string_of_kwargs.split(","))}
    {'n': '6', 'm': '10'}
    

    【讨论】:

      【解决方案4】:

      如果您知道 string_of_kwargs 将始终为 same format(trusted input) ,例如 ',' 分隔的赋值表达式。 https://realpython.com/python-eval-function/

      # convenient(when dict values itself contain '=' or ',') but risky
      # This will evaluate the strings also though, '6' -> 6
      eval(f'dict({string_of_kwargs})')
      
      from ast import literal_eval
      # This will evaluate the strings also though, '6' -> 6
      dict((k, literal_eval(v)) for k, v in (pair.split('=') for pair in s.split(',')))
      

      【讨论】:

      • 鉴于该字符串实际上被称为string_of_kwargs,这可能确实是安全的,并且没有人们想象的那么糟糕。不过,我并没有真正看到与答案第二部分的联系。 (嵌套的 list-comp 正是我所做的,评估数值可能也是一个好主意,但它与第一​​部分中的 eval 应用完全不同。)
      • 是的,你是对的。我没有注意那个。刚看到问题就想到了eval
      【解决方案5】:

      您可以使用regular expression 分割“,”和“=”字符。 然后,您可以将所有偶数索引作为键,将奇数索引作为字典的值

      
      import re
      
      string_of_kwargs = 'n=6,m=10'
      splitted = re.split('=|,', string_of_kwargs) # This will split on = or ,
      
      # Using python list slicing
      keys = splitted[0::2] # get all the keys in splitted
      values = splitted[1::2] # get all the values in splitted
      
      
      

      【讨论】:

        【解决方案6】:

        使用正则表达式 findall 分割文本,并用它来创建字典对

        import re
        string_of_kwargs = 'n=6,m=10'
        x=re.findall(r"[\w']+", string_of_kwargs )
        your_dict = dict(zip(x[::2], x[1::2]))
        

        【讨论】:

        • 为什么不{k: v for k, v in re.findall("(.+?)=(.+?)", string_of_kwargs)}
        猜你喜欢
        • 2018-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-30
        • 2023-03-04
        • 2017-02-18
        • 1970-01-01
        相关资源
        最近更新 更多