安全地解压缩str.split的结果

时间:2017-06-17 20:19:48

标签: python python-3.x iterable-unpacking

我经常对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)

不理想,当"Thisisastring"中的aNone中的""b中的a, *b = mystr.split(" ", 1) b = b[0] if b else "" 所需的结果为*varname时。

有很多黑客可以解决这个问题。我见过的最优雅的是:

obj1 ... objN

不太漂亮,而且对Python新人非常困惑。

那么最恐怖的方式是什么?将返回值存储在变量中并使用if块? console.log黑客?还有别的吗?

3 个答案:

答案 0 :(得分:8)

这看起来非常适合str.partition

>>> a, _, b = "This is a string".partition(" ")
>>> a
'This'
>>> b
'is a string'
>>> a, _, b = "Thisisastring".partition(" ")
>>> a
'Thisisastring'
>>> b
''
>>>

答案 1 :(得分:2)

如何在最后添加默认值并丢弃未使用的默认值?

>>> 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', '', '')

答案 2 :(得分:1)

*varname hack对我来说似乎非常诡异:

  • 与处理函数参数的方式类似

  • 如果需要,您可以使用单行或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]作为一个字符串。 我完全承认默认的定义是模糊的,但如果你喜欢这种效果,你可以进行改进直到它符合你的审美。一般来说,这都是关于适合自己风格的。