How do I convert snake_case to camelCase (and vice versa) in Python?

Asked

Viewed 476 times

4

How could I, in any way pythonic possible, convert a string snake_case for camelCase ?

Example:

  snake1 = 'minha_string_snake_case' # minhaStringSnakeCase
  snake2 = '_teste_string' #  _TestString

3 answers

2


A simpler version would be to use regular expression from the beginning. In the module re there is the function sub() which allows substitutions to be made inside a string using regular expression.

More than that, re.sub() allows you to pass a function to process the found pattern and return a string to the replacement, which fits very well in your case.

Soon:

>>> import re

For camelCase:

>>> camel = re.sub(r'[a-zA-Z]_([a-zA-Z])',
...                lambda _ : _.group(0)[0] + _.group(1).upper(),
...                '_para_camel_case')
>>> camel
'_paraCamelCase'

For snake_case:

>>> snake = re.sub('[A-Z]',
...                lambda _ : '_' +  _.group(0).lower(),
...                '_paraSnakeCase')
>>> snake
'_para_snake_case'

Perhaps there will be more suitable regular expressions, but there it is for you.

1

To convert to Camelcase, simply break the string into the "_" and capitalize the first letter - and this can be done in a single reasonably readable expression (without the need to declare function, or itertools methods):

CamelCase = "".join(word.capitalize() for word in snake_case.split("_"))

If you need the first letter to be lowercase, you can either follow the expression above with a simple and readable CamelCase = CamelCase[0].lower() + CamerlCase[1:], u put a counter and an uninterrupted if in the first expression to not capitalize the first word:

CamelCase = "".join((word.capitalize() if i else word)for i, word in enumerate(snake_case.split("_")))

To return, it is necessary to process letter by letter, but it can also be done in a single expression:

 snake_case = "".join(("_" + letter.lower()) if letter.isupper() else letter for letter in CamelCase).strip("_")

1

One way to do it is to work with list comprehensions and join, as in the example below:

import itertools

def flatten(lista):
    return list(itertools.chain(*lista))

def converte_para_camel_string(valor):
    valor = valor.split('_')
    if valor[0] == '':
        valor[0] = '_'
    ret = [valor[0]]
    ret.append([x.capitalize() for x in valor[1:]])
    ret = flatten(ret)
    return ''.join(ret)

and you will have the following result:

snake1 = converte_para_camel_string('minha_string_snake_case') # minhaStringSnakeCase
snake2 = converte_para_camel_string('_teste_string') #  _TestString

Already to convert Camel case to Snake, you can use regular expressions as follows:

import re

def converte_para_snake_string(valor):
    valor = re.findall('[A-Z]*[^A-Z]*', valor) # dá um split nas letras maiúsculas
    if valor[0] == '_':
        valor[0] = ''
    valor = [x.lower() for x in valor]
    return '_'.join(valor)[:-1]

This will return:

string1 = converte_para_snake_string('testeString') #teste_string
string2 = converte_para_snake_string('_TesteString') #_teste_string
  • what itertools.chain(*lista) does exactly, @Felipeavelar?

  • 1

    It takes each element of the list, because what happens is that it returns a list within a list and, to give the join, i need it to be just a list of strings. That’s why I make the list linear (Flatten)

  • The _ before is as follows: Some languages, such as PHP, use protected or private method statements with _. That’s the only mutiny I want him there!

  • It will be good, I will make a plugin for Sublime Text :)

  • In Python, a _ before it is protected by convention. Private is implemented by the language with __, as can be seen in that reply

  • Curiosity: Is there any problem in using the function map? something like ''.join(map('minha_string'.split('_'), lambda x: x.capitalize()))?

  • I haven’t tested it, but I imagine it’s a problem when you start with _ and he will always give _ upcase_ in the first letter...

  • 2

    This is definitely not pythonico.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.