有没有办法在 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 太多值无法解包”