패턴이나 모든 n 요소를 포함하지 않을 때 Python에서 문자열을 어떻게 안정적으로 분할합니까?
Perl에서는 다음을 수행 할 수 있습니다.
my ($x, $y) = split /:/, $str;
그리고 문자열에 패턴이 포함되어 있는지 여부에 관계없이 작동합니다.
그러나 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- 튜플을 반환합니다.
Python 3.x의 또 다른 대안은 확장 된 반복 가능한 압축 풀기 를 사용하는 것입니다 .
>>> a, *b = 'foo'.split(':')
>>> a, b
('foo', [])
이렇게하면 첫 번째 분할 항목이에 할당되고 a
나머지 항목 목록 (있는 경우) 이에 할당 됩니다 b
.
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;
주의 : 우리는 사용하지 말아야 $a
와 $b
함께 사용할 때 특별한 의미를 갖고 있기 때문에 일반적으로 펄 sort
. 여기에서는 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
Whereas in the Perl equivalent, the array (@b
) is greedy, and the scalar $c
is 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";
Gives:
Use of uninitialized value $c in concatenation (.) or string at gash.pl line 8.
a: one b: two three four c:
You are always free to catch the exception.
For example:
some_string = "foo"
try:
a, b = some_string.split(":")
except ValueError:
a = some_string
b = ""
If assigning the whole original string to a
and an empty string to b
is the desired behaviour, I would probably use str.partition()
as eugene y suggests. However, this solution gives you more control over exactly what happens when there is no separator in the string, which might be useful in some cases.
split
will always return a list. a, b = ...
will always expect list length to be two. You can use something like l = string.split(':'); a = l[0]; ...
.
Here is a one liner: a, b = (string.split(':') + [None]*2)[:2]
How about using Regular Expressions:
import re
string = 'one:two:three:four'
in 3.X:
a, *b = re.split(':', string)
in 2.X:
a, b = re.split(':', string)[0], re.split(':', string)[1:]
This way you can also use regular expressions to split(i. e. \d)
'development' 카테고리의 다른 글
Observable 목록을 결합하고 모두 완료 될 때까지 기다립니다. (0) | 2020.10.21 |
---|---|
WRITE_SETTINGS 권한을 얻을 수 없습니다. (0) | 2020.10.20 |
날짜가 주어진 범위에 있는지 확인하는 방법은 무엇입니까? (0) | 2020.10.20 |
sed를 사용하여 파일 이름 바꾸기 (0) | 2020.10.20 |
Magento 제품은 카테고리에 표시되지 않습니다. (0) | 2020.10.20 |