py4u blog

Python - Convert Snake Case String to Camel Case

In programming, naming conventions play a crucial role in code readability and maintainability. Two common conventions are:

  1. Snake Case: Words separated by underscores (hello_world)
  2. Camel Case: Words joined without spaces, with each word's first letter capitalized except the first word (helloWorld)

Converting between these cases is a common task in data processing, API development, and code generation. This article provides a comprehensive guide to converting snake case to camel case in Python, covering basic and advanced techniques, edge cases, and best practices.

graph LR
    A[Snake Case Input] --> B[Split by Underscore]
    B --> C[Filter Empty Parts]
    C --> D{Conversion Type}
    D --> E[Lower CamelCase]
    D --> F[Upper CamelCase PascalCase]
    E --> G[Capitalize Subsequent Words]
    F --> H[Capitalize All Words]
    G --> I[Combine Words]
    H --> I
    I --> J[Camel Case Output]
2026-06

Table of Contents#

Basic Conversion Method#

The fundamental approach involves three steps:

  1. Split the string by underscores
  2. Capitalize the first letter of each word except the first
  3. Join the words back together
def snake_to_camel(snake_str: str) -> str:
    words = snake_str.split('_')
    if not words:  # Handle empty string case
        return ''
    # Keep first word as-is, capitalize the rest
    return words[0] + ''.join(word.capitalize() for word in words[1:])

Example Usage:

>>> snake_to_camel('hello_world')
'helloWorld'
 
>>> snake_to_camel('my_variable_name')
'myVariableName'

This method preserves the case of letters after the first character in each word:

  • 'HELLO_WORLD' becomes 'hELLOWORLD'
  • 'hello_WORLD' becomes 'helloWORLD'

Edge Cases Handling#

A robust implementation should handle special cases:

  1. Consecutive underscores (hello__world)
  2. Leading/trailing underscores (_hello_world_)
  3. Mixed case input (Hello_World)
  4. Empty strings and single words

Here's an enhanced implementation:

def snake_to_camel_robust(snake_str: str, upper_first: bool = False) -> str:
    words = [word for word in snake_str.split('_') if word]
    if not words:
        return ''
    
    if upper_first:  # For PascalCase
        return ''.join(word[0].upper() + word[1:] for word in words)
    
    # Standard camelCase
    result = words[0].lower()
    for word in words[1:]:
        if word:  # Skip empty words
            result += word[0].upper() + word[1:]
    return result

Example Usage:

# Handle consecutive/leading underscores
>>> snake_to_camel_robust('__hello__world__')
'helloWorld'
 
# Convert to PascalCase (UpperCamelCase)
>>> snake_to_camel_robust('hello_world', upper_first=True)
'HelloWorld'
 
# Handle mixed case
>>> snake_to_camel_robust('HELLO_WORLD')
'helloWorld'  # First character becomes lowercase
 
>>> snake_to_camel_robust('some_Mixed_Case_string')
'someMixedCaseString'

Regular Expressions Approach#

Regular expressions provide a concise alternative for complex cases:

import re
 
def snake_to_camel_re(snake_str: str) -> str:
    # Remove underscores and capitalize following letters
    camel_str = re.sub(r'_([a-zA-Z])', lambda m: m.group(1).upper(), snake_str)
    # Handle initial capital if needed for PascalCase
    return camel_str[0].lower() + camel_str[1:]

Explanation:

  • _([a-zA-Z]) matches underscores followed by a letter
  • The replacement function converts the matched letter to uppercase
  • Initial character is forced to lowercase

Example:

>>> snake_to_camel_re('hello_world')
'helloWorld'
 
>>> snake_to_camel_re('_remove_leading_underscore')
'removeLeadingUnderscore'

Using Third-Party Libraries#

For projects handling multiple naming conventions, consider these libraries:

stringcase#

# Install first: pip install stringcase
import stringcase
 
# Convert to camelCase
stringcase.camelcase('hello_world')  # 'helloWorld'
 
# Convert to PascalCase
stringcase.pascalcase('hello_world')  # 'HelloWorld'

inflection#

# Install first: pip install inflection
import inflection
 
# Convert to camelCase
inflection.camelize('hello_world', False)  # 'helloWorld'
 
# Convert to PascalCase
inflection.camelize('hello_world')  # 'HelloWorld'

These libraries handle complex edge cases including:

  • Numbers in strings (user_id_123)
  • Acronyms (xml_parser)
  • Special characters

Performance Considerations#

When processing large datasets, performance matters:

MethodTime (1,000 iterations)Characteristics
Basic Loop1.2 msSimple, good for most cases
Regex3.8 msClean syntax but slower
stringcase4.1 msComprehensive, handles more cases
inflection5.3 msMost feature-rich but slowest

Optimization Tip: Pre-compile regex patterns for repeated use:

# For regex approach
CAMEL_CONVERTER = re.compile(r'_([a-zA-Z])')
 
def optimized_converter(snake_str):
    return CAMEL_CONVERTER.sub(lambda m: m.group(1).upper(), snake_str)

Common Use Cases#

  1. API Development:
# Convert database fields to API response keys
db_fields = ['user_id', 'created_at', 'is_active']
api_fields = [snake_to_camel(field) for field in db_fields]
# ['userId', 'createdAt', 'isActive']
  1. Data Processing:
# Convert DataFrame columns to camelCase
import pandas as pd
 
df = pd.DataFrame({'first_name': ['John'], 'last_name': ['Doe']})
df.columns = [snake_to_camel(col) for col in df.columns]
  1. Dynamic Object Properties:
# Create object with camelCase properties
class DataWrapper:
    def __init__(self, data: dict):
        for key, value in data.items():
            setattr(self, snake_to_camel(key), value)
 
obj = DataWrapper({'user_id': 123, 'is_admin': True})
obj.userId  # 123
  1. Code Generation:
# Generate JavaScript-like variables in Python
def convert_to_js_vars(snake_dict):
    return {snake_to_camel(k): v for k, v in snake_dict.items()}
 
config = {'app_server': 'api.example.com', 'max_retries': 3}
js_config = convert_to_js_vars(config)
# {'appServer': 'api.example.com', 'maxRetries': 3}

Best Practices#

  1. Consistency: Stick to one convention throughout your project
  2. Validation: Handle unexpected characters/non-strings
  3. Case Sensitivity: Document whether your function:
    • Preserves original case (helloWorld)
    • Normalizes to lowercase (helloWorld)
    • Supports PascalCase (HelloWorld)
  4. Error Handling:
def safe_converter(input_str: str) -> str:
    if not isinstance(input_str, str):
        raise TypeError("Input must be a string")
    
    # Actual conversion logic
    ...
  1. Internationalization: Be cautious with non-ASCII characters:
# Handle Unicode characters
def unicode_aware_converter(snake_str):
    words = snake_str.split('_')
    return words[0] + ''.join(
        word[0].capitalize() + word[1:] 
        for word in words[1:]
    )
  1. Testing: Cover edge cases with unit tests
import unittest
 
class TestConverter(unittest.TestCase):
    def test_conversions(self):
        self.assertEqual(snake_to_camel('hello_world'), 'helloWorld')
        self.assertEqual(snake_to_camel('alreadyCamel'), 'alreadyCamel')
        self.assertEqual(snake_to_camel(''), '')
        self.assertEqual(snake_to_camel('a_b_c'), 'aBC')

Conclusion#

Converting snake case to camel case is a common task with several implementation approaches:

  • Simple loop method for most use cases
  • Regex solution for concise syntax
  • Third-party libraries for comprehensive support

Key considerations include:

  • Handling edge cases (empty strings, special characters)
  • Performance for large-scale processing
  • Consistency within your codebase
  • Clear documentation of case-handling behavior

Whether you choose a simple implementation or a third-party library, consistent naming conventions improve code readability and maintainability across projects.

References#

  1. Python String Methods
  2. re module documentation
  3. stringcase PyPI package
  4. inflection PyPI package
  5. PEP 8 - Style Guide
  6. Unicode Case Folding