在 Perl 中我可以这样做:
my ($x, $y) = split /:/, $str;
无论字符串是否包含模式,它都会起作用。
然而,在 Python 中这是行不通的:
a, b = "foo".split(":") # ValueError: not enough values to unpack
在这种情况下防止错误的规范方法是什么?
原文由 planetp 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 Perl 中我可以这样做:
my ($x, $y) = split /:/, $str;
无论字符串是否包含模式,它都会起作用。
然而,在 Python 中这是行不通的:
a, b = "foo".split(":") # ValueError: not enough values to unpack
在这种情况下防止错误的规范方法是什么?
原文由 planetp 发布,翻译遵循 CC BY-SA 4.0 许可协议
由于您使用的是 Python 3,因此很容易。 PEP 3132 在分配给元组时引入了一种受欢迎的语法简化 - _扩展的可迭代拆包_。在过去,如果给元组中的变量赋值,则赋值左边的项数必须与右边的项数完全相等。
在 Python 3 中,我们可以通过前缀星号 * 将左侧的任何变量指定为列表。这将获取尽可能多的值,同时仍将变量填充到其右侧(因此它不必是最右侧的项目)。当我们不知道元组的长度时,这避免了许多讨厌的切片。
a, *b = "foo".split(":")
print("a:", a, "b:", b)
给出:
a: foo b: []
编辑以下评论和讨论:
与 Perl 版本相比,这是相当不同的,但它是 Python (3) 的方式。与 Perl 版本相比, re.split()
会更相似,但是调用 RE 引擎来拆分单个字符是不必要的开销。
在 Python 中使用多个元素:
s = 'hello:world:sailor'
a, *b = s.split(":")
print("a:", a, "b:", b)
给出:
a: hello b: ['world', 'sailor']
然而在 Perl 中:
my $s = 'hello:world:sailor';
my ($a, $b) = split /:/, $s;
print "a: $a b: $b\n";
给出:
a: hello b: world
可以看出,在 Perl 中附加元素被忽略或丢失。如果需要,这在 Python 中很容易复制:
s = 'hello:world:sailor'
a, *b = s.split(":")
b = b[0]
print("a:", a, "b:", b)
所以, a, *b = s.split(":")
在 Perl 中等价的是
my ($a, @b) = split /:/, $s;
注意:我们不应该在一般 Perl 中使用 $a
和 $b
因为它们在与 sort
一起使用时具有特殊含义我在这里使用它们是为了与 Python 示例保持一致。
Python 确实有一个额外的技巧,我们可以解包到左侧元组中的任何元素:
s = "one:two:three:four"
a, *b, c = s.split(':')
print("a:", a, "b:", b, "c:", c)
给出:
a: one b: ['two', 'three'] c: four
而在 Perl 等效项中,数组 ( @b
) 是贪婪的,而标量 $c
是 undef
use strict;
use warnings;
my $s = 'one:two:three:four';
my ($a, @b, $c) = split /:/, $s;
print "a: $a b: @b c: $c\n";
给出:
Use of uninitialized value $c in concatenation (.) or string at gash.pl line 8.
a: one b: two three four c:
原文由 cdarke 发布,翻译遵循 CC BY-SA 3.0 许可协议
4 回答4.4k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
1 回答3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
1 回答4.5k 阅读✓ 已解决
1 回答3.8k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
如果你只分成两部分(就像你的例子),你可以使用
str.partition()
来保证参数解包大小为 3:str.partition()
总是返回一个三元组,无论是否找到分隔符。Python 3.x 的另一种替代方法是使用 扩展的可迭代拆包:
这会将第一个拆分项目分配给
a
并将剩余项目列表(如果有)分配给b
。