Python Forum

Full Version: CamelCase Conversions
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i need functions that can convert strings to/from CamelCase and underscore_style. i am planning to code these functions unless someone can show me that they already exist.

"MyFunctionName" <-> "my_function_name"

it needs to support Unicode in Python3, to the extent that .upper() and/or .lower() do. i have no need for it to work in Python2. i am looking for references to pre-existing implementations (i can only use what comes with Python, not what needs something to be installed), not for someone to code it.
Just playing with groupby:

from itertools import groupby

def pepify(_str):
    grouped = groupby(_str, lambda char: char.islower())
    keep = lambda seq: ''.join(seq)
    change = lambda seq: ''.join(['_'] + [*seq]).lower()
    replaced = (change(seq) if case is False else keep(seq) for case, seq in grouped)
    return ''.join(replaced).lstrip('_')

pepify('MyFunctionName') --> 'my_function_name'
EDIT:

PEP8 - Programming recommendations

Quote:Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier

So in conformance with PEP8 it should be expressed:

from itertools import groupby

def pepify(_str):
    grouped = groupby(_str, lambda char: char.islower())
    def keep(seq):  return ''.join(seq)
    def change(seq): return ''.join(['_'] + [*seq]).lower()
    replaced = (change(seq) if case is False else keep(seq) for case, seq in grouped)
    return ''.join(replaced).lstrip('_')
There are some libraries for this eg stringcase, Inflection.
λ ptpython
>>> from stringcase import snakecase, camelcase, pascalcase

>>> snakecase('DeathToCamelCase')
'death_to_camel_case'
>>> camelcase('death_to_camel_case')
'deathToCamelCase'
>>> pascalcase('death_to_camel_case')
'DeathToCamelCase'

# Fail on this
>>> snakecase('getHTTPResponseCode')
'get_h_t_t_p_response_code'
This can also be good exercise to do in regex.
For many cases a would a expression like (?!^)([A-Z]+) work.
>>> import re
>>> 
>>> re.sub(r'(?!^)([A-Z]+)', r'_\1', 'DeathToCamelCase').lower() 
'death_to_camel_case'
>>> re.sub(r'(?!^)([A-Z]+)', r'_\1', 'FooBarBaz').lower() 
'foo_bar_baz'
>>> re.sub(r'(?!^)([A-Z]+)', r'_\1', 'getHTTPResponseCode').lower() 
'get_httpresponse_code'
Looking at net so have some made better like eg ((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z])).
(Apr-18-2019, 10:01 AM)snippsat Wrote: [ -> ]
λ ptpython
# Fail on this
>>> snakecase('getHTTPResponseCode')
'get_h_t_t_p_response_code'

It's surprising as with groupby it gives expected result:

>>> pepify('getHTTPResponseCode')
'get_httpresponse_code'
However, for keeping leading underscore it must be adjusted:

>>> pepify('_getHTTPResponseCode')
'get_httpresponse_code'