Conversión de caja de serpiente a caja de camello inferior (lowerCamelCase)


80

¿Cuál sería una buena manera de convertir de mayúsculas y minúsculas ( my_string) a mayúsculas y minúsculas (myString) en Python 2.7?

La solución obvia es dividir por subrayado, poner en mayúscula cada palabra excepto la primera y volver a unir.

Sin embargo, tengo curiosidad por conocer otras soluciones más idiomáticas o una forma de usar RegExppara lograr esto (¿con algún modificador de caso?)


Que yo sepa, no hay nada para lograr esto de inmediato. ¿Intentó implementar su propia solución?
Frédéric Hamidi

edité mi pregunta, sé que no hay nada integrado, quería encontrar una buena implementación
luca

No creo que esta pregunta esté "fuera de tema" de ninguna manera.
0xc0de

Respuestas:


148
def to_camel_case(snake_str):
    components = snake_str.split('_')
    # We capitalize the first letter of each component except the first one
    # with the 'title' method and join them together.
    return components[0] + ''.join(x.title() for x in components[1:])

Ejemplo:

In [11]: to_camel_case('snake_case')
Out[11]: 'snakeCase'

11
¿A qué otros tipos de datos se aplicaría camelCasing?
jbaiter

20
Bueno, eso no es Python realmente idiomático, que generalmente se adhiere al principio de "Es más fácil pedir perdón que permiso". Con> 3.5, puede agregar sugerencias de tipo si desea seguridad de tipo, pero hacer la verificación de tipo con if-else para funciones que son tan claras como esta (¿qué más podría camelCase posible además de las cadenas?) Es simplemente un mal estilo y excesivo verbosidad en mi libro.
jbaiter

2
Solo quería segundo jbaiter aquí. No es responsabilidad de to_camel_caseasegurarse de que la entrada sea una cadena, es responsabilidad del código de llamada. Pasar una no cadena generará una excepción, lo cual es bueno. Para eso están las excepciones.
kylebebak

@stelios Ni siquiera. ¿Qué pasa con las cadenas vacías? ¿Y qué harías de otra manera? Porque así estás devolviendo a None. No puede evitar un solo error. Si lo pruebas, solo terminarás ocultando su origen. Eso es Python, no Java. No tienes que evitar las excepciones, tienes que tratarlas.
Nuno André

1
Poco de un caso límite, pero si esperas _bara convertirse baren lugar de Bar, a continuación, hacer un ligero pellizco:components = snake_str.lstrip('_').split('_')
bigh_29

15

Aquí hay otra toma, que solo funciona en Python 3.5 y versiones posteriores:

def camel(snake_str):
    first, *others = snake_str.split('_')
    return ''.join([first.lower(), *map(str.title, others)])

No use la comprensión de listas cuando un generador lo haría (es decir, join(...)es mejor que join([...])aquí, porque funciona sin crear una lista).
Vedran Šego

2
Tiene toda la razón, sin embargo, eso no se aplica en este caso particular, ya que lo que se pasa al joinmétodo no es una comprensión sino una lista regular. Si desea evitar la creación de una lista en memoria, puede usar el uso itertools.chain, pero si le preocupa la huella de memoria al convertir la caja de serpiente en camello, tiene problemas mucho mayores. ;-)
Berislav Lopac

Lo siento, lo leí mal (porque llegué aquí buscando PascalCase en lugar de camelCase). No, esto está bien.
Vedran Šego

8

Obligatorio one-liner:

import string

def to_camel_case(s):
    return s[0].lower() + string.capwords(s, sep='_').replace('_', '')[1:] if s else s

Este método falla cuando tiene un subrayado inicial (se omite la primera letra).
siebz0r

3
Aún más corto: return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), name) (ver aquí)
Mathieu Rodic

5
>>> snake_case = "this_is_a_snake_case_string"
>>> l = snake_case.split("_")
>>> print l[0] + "".join(map(str.capitalize, l[1:]))
'thisIsASnakeCaseString'

4

otro trazador de líneas

def to_camel_case(snake_string):
    return snake_string.title().replace("_", "")

4
El primer carácter es en mayúsculas.
SiHa

4

Un poco tarde para esto, pero encontré esto en / r / python hace un par de días:

pip install pyhumps

y luego puedes hacer:

import humps

humps.camelize('jack_in_the_box')  # jackInTheBox
# or
humps.decamelize('rubyTuesdays')  # ruby_tuesdays
# or
humps.pascalize('red_robin')  # RedRobin

1

Sobre la base de la respuesta de Steve, esta versión debería funcionar:

def to_camel_case(snake_case_string):
    titleCaseVersion =  snake_case_string.title().replace("_", "")
    camelCaseVersion = titleCaseVersion[0].lower() + titleCaseVersion[1:]
    return camelCaseVersion

1

Aquí hay una solución que usa expresiones regulares:

import re

def snake_to_camel(text):
    return re.sub('_([a-zA-Z0-9])', lambda m: m.group(1).upper(), text)

0
def to_camel_case(snake_str):
    components = snake_str.split('_')
    return reduce(lambda x, y: x + y.title(), components[1:], components[0])

0

Sin usar listas por comprensión:

def snake_to_camel_case(text_snake):
    return '{}{}'.format(
        text_snake[:1].lower(),
        text_snake.title().replace('_', '')[1:],
    )

0

Así que necesitaba convertir un archivo completo con un montón de parámetros de caso de serpiente en caso de camello. La solución de Mathieu Rodic funcionó mejor. Gracias.

Aquí hay un pequeño script para usarlo en archivos.

import re

f = open("in.txt", "r")
words = f.read()

def to_camel_case3(s):
    return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), s)

f = open("out.txt", "w")
f.write(to_camel_case3(words))

0
def toCamel(snake)
    return ''.join( word.capitalize()
                    for word in snake.split('_') )

Permita que el subrayado sea escapado por un subrayado anterior (por ejemplo, 'Escaped__snake' se convertiría en 'Escaped_Snake', mientras que 'usual_snake' se convierte en 'UsualSnake'. Incluya la prueba ternaria para espacios en blanco.

def toCamel(escaped_snake)
    return ''.join( (word.capitalize(), '_')[word=='')
                    for word in escaped_snake.split('_') )

No use mayúsculas en el primer segmento (es decir, 'tHERE_is_a_snake' se convierte en 'thereIsASnake')

def toCamel(esCAPed_snake)
    words = esCAPed_snake.split('_')
    return words[0].lower() + ''.join( (word.capitalize(), '_')[word=='')
                                       for word in words[1:] )

-2

También se tocamelcasepuede convertir fácilmente de estuche de serpiente a estuche de camello.

Instalar en pc

$ pip install tocamelcase

y luego puedes usarlo así:

import tocamelcase

print(tocamelcase.convert("non_camel_case"))
# -> non_camel_case → NonCamelCase

También existe decamelizela inversa de este módulo.


Esto es PascalCase, por lo que incluso el nombre del módulo es engañoso.
stasdeep
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.