Keep capitals in snake_case to camel case

Viewed 349

Below is my code and I was wondering if there was a way to keep caps the way they are?

Such as "num_to_SMS" would still become "numToSMS"?

def to_camel(ident):
  return ''.join(x.capitalize() or '_' for x in ident.split('_'))

print(to_camel('foo'))
print(to_camel('raw_input'))
print(to_camel('num2words'))
print(to_camel('num_to_SMS'))

So far the last example outputs numToSms not numToSMS as desired.

3 Answers

You could manually uppercase only the first character:

def to_camel(ident):
    return ''.join(x[:1].upper() + x[1:] for x in ident.split('_'))

for s in 'foo', 'raw_input', 'num2words', 'num_to_SMS':
    print(to_camel(s))

Output:

Foo
RawInput
Num2words
NumToSMS

I'm using slices just in case x = ''.

Only uppercase the letter directly following the underscore, don't touch anything else, so .capitalize() is paradoxically not the droid you want. Here's the regex approach, based on Making letters uppercase using re.sub:

>>> re.sub('_.', lambda mat: mat.group(0).upper(), 'num_to_SMS')

'num_To_SMS'

(In re.sub, the repl argument can be a function ('callable'), in which case it's passed the Match object mat. We can use this to workaround Python lacking extended regex operators like uppercase \U, which PERL etc. have. There are also third-party Python packages for those.)

try:

def to_camel(ident):
    lst = ident.split('_')
    return ''.join(x[:1].upper() + x[1:] if not ((x.isupper() and x.isalpha()) 
    or lst.index(x)==0) else (x if lst.index(x) != 0 else x.lower()) for x in lst)

this code forces to capitalize the first letter of the words if they are not the starting word and are not all capital, and keeps the all capital words as it is if the word is not the starting one.

output:

foo
rawInput
num2words
numToSMS
Related