我经常对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"
中的a
和None
中的""
或b
中的a, *b = mystr.split(" ", 1)
b = b[0] if b else ""
所需的结果为*varname
时。
有很多黑客可以解决这个问题。我见过的最优雅的是:
obj1 ... objN
不太漂亮,而且对Python新人非常困惑。
那么最恐怖的方式是什么?将返回值存储在变量中并使用if块? console.log
黑客?还有别的吗?
答案 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]作为一个字符串。 我完全承认默认的定义是模糊的,但如果你喜欢这种效果,你可以进行改进直到它符合你的审美。一般来说,这都是关于适合自己风格的。