Perlでは、次のことができます。
my ($x, $y) = split /:/, $str;
また、文字列にパターンが含まれているかどうかにかかわらず機能します。
Pythonでは、しかしこれは機能しません:
a, b = "foo".split(":") # ValueError: not enough values to unpack
そのような場合にエラーを防ぐための標準的な方法は何ですか?
(例のように)2つの部分だけに分割する場合は、 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です。簡単です。PEP3132は、タプルに割り当てる際の構文の歓迎すべき簡素化を導入しました-拡張反復可能アンパック。タプルの変数に割り当てる場合、割り当ての左側の項目の数は右側の項目の数と正確に等しくなければなりません。
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)
_
したがって、Perlでa, *b = s.split(":")
と同等なものは
_my ($a, @b) = split /:/, $s;
_
NB:sort
と共に使用すると特別な意味を持つため、一般的なPerlでは_$a
_と_$b
_を使用しないでください。ここではPythonの例との一貫性のためにそれらを使用しました。
Pythonには余分なトリックがあります。左側のTupleの任意の要素に展開できます。
_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:
_
例外はいつでもキャッチできます。
例えば:
_some_string = "foo"
try:
a, b = some_string.split(":")
except ValueError:
a = some_string
b = ""
_
元の文字列全体をa
に割り当て、空の文字列をb
に割り当てることが望ましい場合は、eugene yが示唆するように、おそらくstr.partition()
を使用します。ただし、このソリューションを使用すると、文字列に区切り文字がない場合の動作をより正確に制御できるため、場合によっては便利です。
split
は常にリストを返します。 _a, b = ...
_は常にリストの長さが2であることを期待します。 l = string.split(':'); a = l[0]; ...
のようなものを使用できます。
ライナーは1つです:a, b = (string.split(':') + [None]*2)[:2]
正規表現の使用はどうですか:
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:]
この方法では、正規表現を使用してsplit(i。e。\ d)することもできます