有没有办法在 for 循环中解压 split() 的结果?

Posted

技术标签:

【中文标题】有没有办法在 for 循环中解压 split() 的结果?【英文标题】:Is there a way to unpack the result of split() inside of for-loop? 【发布时间】: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('=') 两次 我想知道是否有办法绕过它,以防我将来不得不解压缩更多这样的值。

【问题讨论】:

你也可以split a string with multiple delimiters。 x=re.findall(r"[\w']",string_of_kwargs);graph_kwargs=i:j for i,j in zip(x[::2],x[1::2]) 【参考方案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)

以上是关于有没有办法在 for 循环中解压 split() 的结果?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Python (3) for 循环中执行条件?

有没有办法在 Java for-each 循环中访问迭代计数器?

Python - 有没有办法在 for 循环中添加“as”别名?

在 for 循环中使用 str.split 时出现“ValueError 太多值无法解包”

使用 for 循环有没有办法控制哪个 # 循环将值附加到列表中?

有没有办法在 for-each 循环迭代开始之前避免空检查? [复制]