Converting Snake Case to Lower Camel Case (lowerCamelCase)
Asked Answered
J

16

120

What would be a good way to convert from snake case (my_string) to lower camel case (myString) in Python 2.7?

The obvious solution is to split by underscore, capitalize each word except the first one and join back together.

However, I'm curious as to other, more idiomatic solutions or a way to use RegExp to achieve this (with some case modifier?)

Janiuszck answered 27/9, 2013 at 14:48 Comment(3)
To my knowledge, there is nothing to achieve this out of the box. Did you try implementing your own solution?Resnick
edited my question, I know there is no built in, I wanted to find a nice implementationJaniuszck
I don't think this question is 'off topic' in any way.Shorn
A
219
def to_camel_case(snake_str):
    return "".join(x.capitalize() for x in snake_str.lower().split("_"))

def to_lower_camel_case(snake_str):
    # We capitalize the first letter of each component except the first one
    # with the 'capitalize' method and join them together.
    camel_string = to_camel_case(snake_str)
    return snake_str[0].lower() + camel_string[1:]

Example:

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

In [12]: to_lower_camel_case('SNAKE_Case')
Out[12]: 'snakeCase'

In [13]: to_lower_camel_case('SNAKE_CASE')
Out[13]: 'snakeCase'
Audry answered 27/9, 2013 at 14:52 Comment(7)
What other datataypes would camelCasing be applicable to?Audry
Well, that's not really idiomatic Python, which generally adheres to the "Easier to ask for forgiveness than permission" principle. With >3.5 you could add type hints if you want type safety, but doing type checking with if-else for functions that are as clear-cut as this (what else could you possible camelCase other than strings?) is just bad style and excessive verbosity in my book.Audry
Just wanted to second jbaiter here. It's not the responsibility of to_camel_case to ensure the input is a string, it's the responsibility of calling code. Passing a non-string will raise an exception, which is good. That's what exceptions are for.Poynter
@stelios Not even. What about empty strings? And what would you do otherwise? Because thus you're returning a None. You can't prevent any single error. If you try it you will only end up shadowing its source. That's Python, not Java. You don't have to avoid exceptions, you have to treat them.Deal
Bit of a corner case, but if you expect _bar to become bar instead of Bar, then make a slight tweak: components = snake_str.lstrip('_').split('_')Dues
I think that it's more correct to call str.capitalize() than str.title() as the title() implies that there are multiple word in a given string, but there should be no space in any of the components.Kermie
Unless I'm confused the call to snake_str.lower() is redundant because .capitalize() will lowercase everything after the first character in each word anyway.Weissman
O
29

Here's yet another take, which works only in Python 3.5 and higher:

def camel(snake_str):
    first, *others = snake_str.split('_')
    return ''.join([first.lower(), *map(str.title, others)])
Osrick answered 24/2, 2017 at 23:57 Comment(3)
Don't use list comprehension when a generator would do (i.e, join(...) is better than join([...]) here, because it works without creating a list).Anomalism
You are absolutely right, however that does not apply in this particular case, as what is passed to the join method is not a comprehension but a regular list. If you want to avoid creating an in-memory list you could use use itertools.chain, but then if you are concerned about memory footprint when converting snake to camel case you have much bigger problems. ;-)Osrick
Sorry, I misread it (because I got here looking for the PascalCase instead of camelCase). No, this is fine.Anomalism
S
26

A little late to this, but I found this on /r/python a couple days ago:

pip install pyhumps

and then you can just do:

import humps

humps.camelize('jack_in_the_box')  # jackInTheBox
# or
humps.decamelize('rubyTuesdays')  # ruby_tuesdays
# or
humps.pascalize('red_robin')  # RedRobin
Sinner answered 6/11, 2018 at 16:41 Comment(2)
This is a nice solution, and as a bonus if you pass in a dictionary, it will camelize the keys but leave the values. Which is perfect for anyone building an API in python but wanting the JSON response to be more JavaScript friendly.Eigenfunction
this also takes care of more complicated cases like _response or APIResponseRhondarhondda
B
13

another one liner

def to_camel_case(snake_string):
    return snake_string.title().replace("_", "")
Brominate answered 7/1, 2016 at 12:55 Comment(3)
First char is Upper Case.Mossback
Useful if you want to convert to a class name, for instance.Tera
While the OP asks for lower-camel-case, this is actually the first stackoverflow example that came up when searching "convert snake case to camel case python". This is what I actually wanted though, so I'm glad it's here.Doornail
H
9

Obligatory one-liner:

import string

def to_camel_case(s):
    return s[0].lower() + string.capwords(s, sep='_').replace('_', '')[1:] if s else s
Hub answered 27/9, 2013 at 14:56 Comment(2)
This method fails when having a leading underscore (first letter gets omitted).Octans
Even shorter: return re.sub(r'_([a-z])', lambda x: x.group(1).upper(), name) (see here)Generate
M
5
>>> snake_case = "this_is_a_snake_case_string"
>>> l = snake_case.split("_")
>>> print l[0] + "".join(map(str.capitalize, l[1:]))
'thisIsASnakeCaseString'
Monkshood answered 27/9, 2013 at 14:54 Comment(0)
N
4

for one-line fans..

''.join((wd.title() if i else wd) for (i,wd) in enumerate(string.split('_')))
Newsboy answered 16/5, 2021 at 15:40 Comment(0)
R
3

Building on Steve's answer, this version should work:

def to_camel_case(snake_case_string):
    titleCaseVersion =  snake_case_string.title().replace("_", "")
    camelCaseVersion = titleCaseVersion[0].lower() + titleCaseVersion[1:]
    return camelCaseVersion
Rinehart answered 5/4, 2016 at 14:58 Comment(0)
C
3

it this too simple?

snake_case is already lowercase. my_string

So if we title the string and remove the underscores MyString

then replace the first character M with the original m we're done.

scase = "my_string"
ccase = scase[0] + scase.title().replace('_', '')[1:]

output: myString

Celeski answered 5/2, 2022 at 15:18 Comment(0)
M
2
def toCamel(snake)
    return ''.join( word.capitalize()
                    for word in snake.split('_') )

Allow underscore to be escaped by a preceding underscore (e.g. 'Escaped__snake' would become 'Escaped_Snake', while 'usual_snake' becomes 'UsualSnake'. Include ternary test for blank.

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

Don't capitalize the 1st segment (i.e, 'tHERE_is_a_snake' becomes 'thereIsASnake')

def toCamel(esCAPed_snake)
    words = esCAPed_snake.split('_')
    return words[0].lower() + ''.join( (word.capitalize(), '_')[word=='')
                                       for word in words[1:] )
Maritsa answered 5/2, 2020 at 7:58 Comment(0)
N
2

I personally use this solution since it is a rolling transformation:

from functools import reduce

def camelize(snake_string: str) -> str:
    return reduce(lambda x, y: x + y.capitalize(), snake_string.split('_'))
Northbound answered 13/4, 2022 at 7:27 Comment(1)
This solution capitalizes the first word if there is a leading underscore.Raffin
D
1

Here is a solution using regular expressions:

import re

def snake_to_camel(text):
    return re.sub('_([a-zA-Z0-9])', lambda m: m.group(1).upper(), text)
Doorn answered 12/11, 2017 at 20:14 Comment(0)
A
1

You can use pydash if you are familiar with lodash.

pip install pydash first.

import pydash  # pip install pydash

assert pydash.snake_case("WriteLine") == "write_line"
assert pydash.snake_case("writeLine") == "write_line"
assert pydash.camel_case("write_line") == "writeLine"
assert pydash.upper_first(pydash.camel_case("write_line")) == "WriteLine"

https://github.com/dgilland/pydash

https://pydash.readthedocs.io/en/latest/

https://pypi.org/project/pydash/

Augsburg answered 5/1, 2022 at 5:9 Comment(0)
T
0
def to_camel_case(snake_str):
    components = snake_str.split('_')
    return reduce(lambda x, y: x + y.title(), components[1:], components[0])
Totter answered 29/1, 2018 at 23:17 Comment(0)
S
0

Without using list comprehensions:

def snake_to_camel_case(text_snake):
    return '{}{}'.format(
        text_snake[:1].lower(),
        text_snake.title().replace('_', '')[1:],
    )
Sciential answered 31/7, 2018 at 23:43 Comment(0)
S
0

So I needed to convert a whole file with bunch of snake case parameters into camel case. The solution by Mathieu Rodic worked best. Thanks.

Here is a little script to use it on files.

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))
Semicentennial answered 28/2, 2019 at 17:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.