How can I simplify this conversion from underscore to camelcase in Python?

I have written the function below that converts underscore to camelcase with first word in lowercase, ie "get_this_value" -> "getThisValue". Also I have requirement to preserve leading and trailing underscores and also double (triple etc.) underscores, if any, ie

"_get__this_value_" -> "_get_ThisValue_".

The code:

def underscore_to_camelcase(value):
    output = ""
    first_word_passed = False
    for word in value.split("_"):
        if not word:
            output += "_"
            continue
        if first_word_passed:
            output += word.capitalize()
        else:
            output += word.lower()
        first_word_passed = True
    return output

I am feeling the code above as written in non-Pythonic style, though it works as expected, so looking how to simplify the code and write it using list comprehensions etc.


Your code is fine. The problem I think you're trying to solve is that if first_word_passed looks a little bit ugly.

One option for fixing this is a generator. We can easily make this return one thing for first entry and another for all subsequent entries. As Python has first-class functions we can get the generator to return the function we want to use to process each word.

We then just need to use the conditional operator so we can handle the blank entries returned by double underscores within a list comprehension.

So if we have a word we call the generator to get the function to use to set the case, and if we don't we just use _ leaving the generator untouched.

def underscore_to_camelcase(value):
    def camelcase(): 
        yield str.lower
        while True:
            yield str.capitalize

    c = camelcase()
    return "".join(c.next()(x) if x else '_' for x in value.split("_"))

This one works except for leaving the first word as lowercase.

def convert(word):
    return ''.join(x.capitalize() or '_' for x in word.split('_'))

(I know this isn't exactly what you asked for, and this thread is quite old, but since it's quite prominent when searching for such conversions on Google I thought I'd add my solution in case it helps anyone else).


I prefer a regular expression, personally. Here's one that is doing the trick for me:

import re
def to_camelcase(s):
    return re.sub(r'(?!^)_([a-zA-Z])', lambda m: m.group(1).upper(), s)

Using unutbu 's tests:

tests = [('get__this_value', 'get_ThisValue'),
         ('_get__this_value', '_get_ThisValue'),
         ('_get__this_value_', '_get_ThisValue_'),
         ('get_this_value', 'getThisValue'),
         ('get__this__value', 'get_This_Value')]

for test, expected in tests:
    assert to_camelcase(test) == expected
链接地址: http://www.djcxy.com/p/31794.html

上一篇: 将列表转换为字符串

下一篇: 如何简化Python中从下划线到camelcase的这种转换?