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?)

luca
fuente
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'
jbaiter
fuente
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)])
Berislav Lopac
fuente
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
Simeon Visser
fuente
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'
Leon Young
fuente
4

otro trazador de líneas

def to_camel_case(snake_string):
    return snake_string.title().replace("_", "")
steve
fuente
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
Glenn Dills
fuente
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
MLev
fuente
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)
Antoine Pinsard
fuente
0
def to_camel_case(snake_str):
    components = snake_str.split('_')
    return reduce(lambda x, y: x + y.title(), components[1:], components[0])
Chandler Childs
fuente
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:],
    )
Michael Thiesen
fuente
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))
Mike Starov
fuente
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:] )
Bendito Geek
fuente
-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.

abranhe
fuente
Esto es PascalCase, por lo que incluso el nombre del módulo es engañoso.
stasdeep