str.split 的安全解包结果
Safely unpacking results of str.split
我经常因 Python 的可迭代拆包缺乏灵活性而感到沮丧。举个例子:
a, b = "This is a string".split(" ", 1)
工作正常。正如预期的那样,a
包含 "This"
,b
包含 "is a string"
。现在让我们试试这个:
a, b = "Thisisastring".split(" ", 1)
现在,我们得到 ValueError
:
ValueError: not enough values to unpack (expected 2, got 1)
不理想,当期望的结果是 a
中的 "Thisisastring"
和 None
或者更好的是 b
中的 ""
。
有很多技巧可以解决这个问题。我见过的最优雅的是:
a, *b = mystr.split(" ", 1)
b = b[0] if b else ""
不漂亮,Python 新手很困惑。
那么最 Pythonic 的方法是什么?将 return 值存储在变量中并使用 if 块? *varname
黑客攻击?还有别的吗?
这看起来非常适合 str.partition:
>>> a, _, b = "This is a string".partition(" ")
>>> a
'This'
>>> b
'is a string'
>>> a, _, b = "Thisisastring".partition(" ")
>>> a
'Thisisastring'
>>> b
''
>>>
*varname
hack 对我来说似乎非常 pythonic:
类似于函数参数的处理方式
如果需要,允许您使用单行代码或 if 块或不使用任何内容来更正元素的类型
如果您觉得对新用户来说不够清楚,您也可以尝试类似下面的方法
def default(default, tuple_value):
return tuple(map(lambda x: x if x is not None else default, tuple_value))
然后你可以这样做
a, *b = default("", s.split(...))
那么你应该能够相信 b[0] 是一个字符串。
我完全承认默认的定义是晦涩难懂的,但是如果你喜欢这个效果,你可以细化直到它符合你的审美。总的来说,这就是您的风格。
在最后添加默认值并丢弃未使用的怎么样?
>>> a, b, *_ = "This is a string".split(" ", 1) + ['']
>>> a, b
('This', 'is a string')
>>> a, b, *_ = "Thisisastring".split(" ", 1) + ['']
>>> a, b
('Thisisastring', '')
>>> a, b, c, *_ = "Thisisastring".split(" ", 2) + [''] * 2
>>> a, b, c
('Thisisastring', '', '')
类似(也适用于 Python 2):
>>> a, b, c = ("Thisisastring".split(" ", 2) + [''] * 2)[:3]
>>> a, b, c
('Thisisastring', '', '')
我经常因 Python 的可迭代拆包缺乏灵活性而感到沮丧。举个例子:
a, b = "This is a string".split(" ", 1)
工作正常。正如预期的那样,a
包含 "This"
,b
包含 "is a string"
。现在让我们试试这个:
a, b = "Thisisastring".split(" ", 1)
现在,我们得到 ValueError
:
ValueError: not enough values to unpack (expected 2, got 1)
不理想,当期望的结果是 a
中的 "Thisisastring"
和 None
或者更好的是 b
中的 ""
。
有很多技巧可以解决这个问题。我见过的最优雅的是:
a, *b = mystr.split(" ", 1)
b = b[0] if b else ""
不漂亮,Python 新手很困惑。
那么最 Pythonic 的方法是什么?将 return 值存储在变量中并使用 if 块? *varname
黑客攻击?还有别的吗?
这看起来非常适合 str.partition:
>>> a, _, b = "This is a string".partition(" ")
>>> a
'This'
>>> b
'is a string'
>>> a, _, b = "Thisisastring".partition(" ")
>>> a
'Thisisastring'
>>> b
''
>>>
*varname
hack 对我来说似乎非常 pythonic:
类似于函数参数的处理方式
如果需要,允许您使用单行代码或 if 块或不使用任何内容来更正元素的类型
如果您觉得对新用户来说不够清楚,您也可以尝试类似下面的方法
def default(default, tuple_value):
return tuple(map(lambda x: x if x is not None else default, tuple_value))
然后你可以这样做
a, *b = default("", s.split(...))
那么你应该能够相信 b[0] 是一个字符串。 我完全承认默认的定义是晦涩难懂的,但是如果你喜欢这个效果,你可以细化直到它符合你的审美。总的来说,这就是您的风格。
在最后添加默认值并丢弃未使用的怎么样?
>>> a, b, *_ = "This is a string".split(" ", 1) + ['']
>>> a, b
('This', 'is a string')
>>> a, b, *_ = "Thisisastring".split(" ", 1) + ['']
>>> a, b
('Thisisastring', '')
>>> a, b, c, *_ = "Thisisastring".split(" ", 2) + [''] * 2
>>> a, b, c
('Thisisastring', '', '')
类似(也适用于 Python 2):
>>> a, b, c = ("Thisisastring".split(" ", 2) + [''] * 2)[:3]
>>> a, b, c
('Thisisastring', '', '')