recortar - separar palabra en letras python
¿Cómo divido de manera confiable una cadena en Python, cuando puede no contener el patrón o todos los n elementos? (5)
¿Qué tal el uso de expresiones regulares:
import re
string = ''one:two:three:four''
en 3.X:
a, *b = re.split('':'', string)
en 2.X:
a, b = re.split('':'', string)[0], re.split('':'', string)[1:]
De esta manera también puede usar expresiones regulares para dividir (es decir, / d)
En Perl puedo hacer:
my ($x, $y) = split /:/, $str;
Y funcionará si la cadena contiene o no el patrón.
En Python, sin embargo, esto no funcionará:
a, b = "foo".split(":") # ValueError: not enough values to unpack
¿Cuál es la forma canónica de prevenir errores en tales casos?
Como estás en Python 3, es fácil. PEP 3132 introdujo una simplificación bienvenida de la sintaxis cuando se asigna a tuplas: desempaquetado iterable extendido . En el pasado, si asignaba variables a una tupla, el número de elementos a la izquierda de la asignación debe ser exactamente igual al de la derecha.
En Python 3 podemos designar cualquier variable de la izquierda como una lista con un asterisco *. Eso tomará tantos valores como sea posible, mientras sigue poblando las variables a su derecha (por lo que no necesita ser el elemento más a la derecha). Esto evita muchas rebanadas desagradables cuando no sabemos la longitud de una tupla.
a, *b = "foo".split(":")
print("a:", a, "b:", b)
Da:
a: foo b: []
EDITE los siguientes comentarios y discusión:
En comparación con la versión Perl, esto es considerablemente diferente, pero es la forma Python (3).
En comparación con la versión Perl,
re.split()
sería más similar, sin embargo, invocar el motor RE para dividir en torno a un solo carácter es una sobrecarga innecesaria.
Con múltiples elementos en Python:
s = ''hello:world:sailor''
a, *b = s.split(":")
print("a:", a, "b:", b)
da:
a: hello b: [''world'', ''sailor'']
Sin embargo en Perl:
my $s = ''hello:world:sailor'';
my ($a, $b) = split /:/, $s;
print "a: $a b: $b/n";
da:
a: hello b: world
Se puede ver que los elementos adicionales se ignoran o se pierden en Perl. Eso es bastante fácil de replicar en Python si es necesario:
s = ''hello:world:sailor''
a, *b = s.split(":")
b = b[0]
print("a:", a, "b:", b)
Entonces,
a, *b = s.split(":")
equivalente en Perl sería
my ($a, @b) = split /:/, $s;
NB: no deberíamos usar
$a
y
$b
en general Perl ya que tienen un significado especial cuando se usan con
sort
.
Los he usado aquí por coherencia con el ejemplo de Python.
Python tiene un truco adicional bajo la manga, podemos descomprimir en cualquier elemento de la tupla de la izquierda:
s = "one:two:three:four"
a, *b, c = s.split('':'')
print("a:", a, "b:", b, "c:", c)
Da:
a: one b: [''two'', ''three''] c: four
Mientras que en el equivalente de Perl, la matriz (
@b
) es codiciosa y el escalar
$c
es
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";
Da:
Use of uninitialized value $c in concatenation (.) or string at gash.pl line 8.
a: one b: two three four c:
Si se divide en solo dos partes (como en su ejemplo), puede usar
str.partition()
para obtener un argumento garantizado que desempaque el tamaño de 3:
>>> a, sep, b = ''foo''.partition('':'')
>>> a, sep, b
(''foo'', '''', '''')
str.partition()
siempre devuelve una tupla de 3, ya sea que se encuentre el separador o no.
Otra alternativa para Python 3.x es usar un desempaquetado iterable extendido :
>>> a, *b = ''foo''.split('':'')
>>> a, b
(''foo'', [])
Esto asigna el primer elemento dividido a
b
la lista de elementos restantes (si corresponde) a
b
.
Siempre eres libre de atrapar la excepción.
Por ejemplo:
some_string = "foo"
try:
a, b = some_string.split(":")
except ValueError:
a = some_string
b = ""
Si asignar la cadena original completa a
b
una cadena vacía a
b
es el comportamiento deseado, probablemente usaría
str.partition()
como eugene y sugiere.
Sin embargo, esta solución le brinda más control sobre lo que sucede exactamente cuando no hay un separador en la cadena, lo que puede ser útil en algunos casos.
split
siempre devolverá una lista.
a, b = ...
siempre esperará que la longitud de la lista sea dos.
Puede usar algo como
l = string.split('':''); a = l[0]; ...
l = string.split('':''); a = l[0]; ...
l = string.split('':''); a = l[0]; ...
Aquí hay una línea:
a, b = (string.split('':'') + [None]*2)[:2]