如何可靠地在Python中分割string?
在Perl中,我可以这样做:
my ($x, $y) = split /:/, $str;
不pipestring是否包含模式,它都会起作用。
在Python中,但是这不起作用:
a, b = "foo".split(":") # ValueError: not enough values to unpack
在这种情况下防止错误的规范方法是什么?
如果你分裂成两部分(就像你的例子),你可以使用str.partition()
来获得一个保证参数的解包大小为3:
>>> a, sep, b = "foo".partition(":") >>> a, sep, b ('foo', '', '')
str.partition()
总是返回一个3元组,无论是否find分隔符。
Python 3的另一个替代方法是使用扩展解包,如@ cdarke的答案中所述 :
>>> a, *b = "foo".split(":") >>> a, b ('foo', [])
这将第一个拆分项分配给a
,剩余项目列表(如果有的话)分配给b
。
既然你是在Python 3,那很简单。 PEP 3132引入了对赋值给元组的语法的一个受欢迎的简化 – 扩展的迭代解包 。 过去,如果赋值给一个元组中的variables,赋值左边的项目数量必须与右边的项目数量完全相同。
在Python 3中,我们可以用星号*作为前缀来将左侧的任何variables指定为列表。 这将尽可能多地获取值,同时仍然将variables填充到右侧(所以它不一定是最右边的项目)。 当我们不知道元组的长度时,这避免了许多令人讨厌的切片。
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: $ab: $b\n";
得到:
a: hello b: world
可以看出,在Perl中,其他元素被忽略或丢失。 如果需要,在Python中复制相当容易:
s = 'hello:world:sailor' a, *b = s.split(":") b = b[0] print("a:", a, "b:", b)
所以,在Perl中, a, *b = s.split(":")
等价的
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: $ab: @bc: $c\n";
得到:
Use of uninitialized value $c in concatenation (.) or string at gash.pl line 8. a: one b: two three four c:
你总是可以自由地发现exception。
例如:
some_string = "foo" try: a, b = some_string.split(":") except ValueError: a = some_string b = ""
如果将整个原始string分配给a
,将空string分配给b
是所需的行为,那么我可能会使用str.partition()
作为eugene y的build议。 但是,这种解决scheme可以让您更精确地控制string中没有分隔符时发生的情况,这在某些情况下可能会有用。
split
总是会返回一个列表。 a, b = ...
总是期望列表长度是两个。 你可以使用像l = string.split(':'); a = l[0]; ...
l = string.split(':'); a = l[0]; ...
l = string.split(':'); a = l[0]; ...
这里是一个单行: a, b = (string.split(':') + [None]*2)[:2]
如何使用正则expression式:
import re string = 'one:two:three:four'
在3.X中:
a, *b = re.split(':', string)
在2.X:
a, b = re.split(':', string)[0], re.split(':', string)[1:]
这样你也可以使用正则expression式来分割(即\ d)