TL;DR

  • Converting to Lowercase -> lower()
  • Caseless String matching/comparison -> casefold()

casefold() is a text normalization function like lower() that is specifically designed to remove upper- or lower-case distinctions for the purposes of comparison. It is another form of normalizing text that may initially appear to be very similar to lower() because generally, the results are the same. As of Unicode 13.0.0, only ~300 of ~150,000 characters produced differing results when passed through lower() and casefold(). @dlukes' answer has the code to identify the characters that generate those differing results.

To answer your other two questions:

  • use lower() when you specifically want to ensure a character is lowercase, like for presenting to users or persisting data
  • use casefold() when you want to compare that result to another casefold-ed value.

Other Material

I suggest you take a closer look into what case folding actually is, so here's a good start: W3 Case Folding Wiki

Another source: Elastic.co Case Folding

Edit: I just recently found another very good related answer to a slightly different question here on SO (doing a case-insensitive string comparison)


Performance

Using this snippet, you can get a sense for the performance between the two:

import sys
from timeit import timeit

unicode_codepoints = tuple(map(chr, range(sys.maxunicode)))

def compute_lower():
    return tuple(codepoint.lower() for codepoint in unicode_codepoints)

def compute_casefold():
    return tuple(codepoint.casefold() for codepoint in unicode_codepoints)

timer_repeat = 1000

print(f"time to compute lower on unicode namespace: {timeit(compute_lower, number = timer_repeat) / timer_repeat} seconds")
print(f"time to compute casefold on unicode namespace: {timeit(compute_casefold, number = timer_repeat) / timer_repeat} seconds")

print(f"number of distinct characters from lower: {len(set(compute_lower()))}")
print(f"number of distinct characters from casefold: {len(set(compute_casefold()))}")

Running this, you'll get the results that the two are overwhelmingly the same in both performance and the number of distinct characters returned

time to compute lower on unicode namespace: 0.137255663 seconds
time to compute casefold on unicode namespace: 0.136321374 seconds
number of distinct characters from lower: 1112719
number of distinct characters from casefold: 1112694

If you run the numbers, that means it takes about 1.6e-07 seconds to run the computation on a single character for either function, so there isn't a performance benefit either way.

Answer from David Culbreth on Stack Overflow
🌐
Reddit
reddit.com › r/learnpython › casefold() vs lower()
r/learnpython on Reddit: casefold() vs lower()
October 12, 2024 -

I just learnt about casefold() and decided to google it to see what it did. Here is w3schools definition:

Definition and Usage The casefold() method returns a string where all the characters are lower case.

This method is similar to the lower() method, but the casefold() method is stronger, more aggressive, meaning that it will convert more characters into lower case, and will find more matches when comparing two strings and both are converted using the casefold() method.

How does one “more aggressively” convert strings to lower case? Meaning, what more can/does it do than lower()?

string.lower() versus string.lower May 26, 2015
r/learnpython
11y ago
How does key=str.casefold work ? Oct 18, 2021
r/learnpython
4y ago
Turn input into lower case Oct 15, 2022
r/learnpython
3y ago
More results from reddit.com
Top answer
1 of 5
111

TL;DR

  • Converting to Lowercase -> lower()
  • Caseless String matching/comparison -> casefold()

casefold() is a text normalization function like lower() that is specifically designed to remove upper- or lower-case distinctions for the purposes of comparison. It is another form of normalizing text that may initially appear to be very similar to lower() because generally, the results are the same. As of Unicode 13.0.0, only ~300 of ~150,000 characters produced differing results when passed through lower() and casefold(). @dlukes' answer has the code to identify the characters that generate those differing results.

To answer your other two questions:

  • use lower() when you specifically want to ensure a character is lowercase, like for presenting to users or persisting data
  • use casefold() when you want to compare that result to another casefold-ed value.

Other Material

I suggest you take a closer look into what case folding actually is, so here's a good start: W3 Case Folding Wiki

Another source: Elastic.co Case Folding

Edit: I just recently found another very good related answer to a slightly different question here on SO (doing a case-insensitive string comparison)


Performance

Using this snippet, you can get a sense for the performance between the two:

import sys
from timeit import timeit

unicode_codepoints = tuple(map(chr, range(sys.maxunicode)))

def compute_lower():
    return tuple(codepoint.lower() for codepoint in unicode_codepoints)

def compute_casefold():
    return tuple(codepoint.casefold() for codepoint in unicode_codepoints)

timer_repeat = 1000

print(f"time to compute lower on unicode namespace: {timeit(compute_lower, number = timer_repeat) / timer_repeat} seconds")
print(f"time to compute casefold on unicode namespace: {timeit(compute_casefold, number = timer_repeat) / timer_repeat} seconds")

print(f"number of distinct characters from lower: {len(set(compute_lower()))}")
print(f"number of distinct characters from casefold: {len(set(compute_casefold()))}")

Running this, you'll get the results that the two are overwhelmingly the same in both performance and the number of distinct characters returned

time to compute lower on unicode namespace: 0.137255663 seconds
time to compute casefold on unicode namespace: 0.136321374 seconds
number of distinct characters from lower: 1112719
number of distinct characters from casefold: 1112694

If you run the numbers, that means it takes about 1.6e-07 seconds to run the computation on a single character for either function, so there isn't a performance benefit either way.

2 of 5
42

Both .lower() and .casefold() act on the full range of Unicode codepoints

There's some confusion in the existing answers, even the accepted one (EDIT: I was referring to this currently outdated version; the current one is fine). The distinction between .lower() and .casefold() has nothing to do with ASCII vs. Unicode, both act on the whole Unicode range of codepoints, just in slightly different ways. But both perform relatively complex mappings which they need to look up in the Unicode database, for instance:

>>> "Ť".lower()
'ť'

Both can involve single-to-multiple codepoint mappings, like we saw with "ß".casefold(). Look what happens to ß when you apply .lower()'s counterpart .upper():

>>> "ß".upper()
'SS'

And the one example I found where .lower() also does this:

>>> list("İ".lower())
['i', '̇']

So the performance claims, like "lower() will require less memory or less time because there are no lookups, and it's only dealing with 26 characters it has to transform", are simply not true.

The vast majority of the time, both operations yield the same thing, but there are a few cases (297 as of Unicode 13.0.0) where they don't. You can identify them like this:

import sys
import unicodedata as ud

print("Unicode version:", ud.unidata_version, "\n")
total = 0
for codepoint in map(chr, range(sys.maxunicode)):
    lower, casefold = codepoint.lower(), codepoint.casefold()
    if lower != casefold:
        total += 1
        for conversion, converted in zip(
            ("orig", "lower", "casefold"),
            (codepoint, lower, casefold)
        ):
            print(conversion, [ud.name(cp) for cp in converted], converted)
        print()
print("Total differences:", total)

When to use which

The Unicode standard covers lowercasing as part of Default Case Conversion in Section 3.13, and Default Case Folding is described right below that. The first paragraph says:

Case folding is related to case conversion. However, the main purpose of case folding is to contribute to caseless matching of strings, whereas the main purpose of case conversion is to put strings into a particular cased form.

My rule of thumb based on this:

  • Want to display a lowercased version of a string to users? Use .lower().
  • Want to do case-insensitive string comparison? Use .casefold().

(As a sidenote, I routinely break this rule of thumb and use .lower() across the board, just because it's shorter to type, the output is overwhelmingly the same, and what differences there are don't affect the languages I typically come across and work with. Don't be like me though ;) )

Just to hammer home that in terms of complexity, both operations are basically the same, they just use slightly different mappings -- this is Unicode's abstract definition of lowercasing:

R2 toLowercase(X): Map each character C in X to Lowercase_Mapping(C).

And this is its abstract definition of case folding:

R4 toCasefold(X): Map each character C in X to Case_Folding(C).

In Python's official documentation

The Python docs are quite clear that this is what the respective methods do, they even point the user to the aforementioned Section 3.13.

They describe .lower() as converting cased characters to lowercase, where cased characters are "those with general category property being one of “Lu” (Letter, uppercase), “Ll” (Letter, lowercase), or “Lt” (Letter, titlecase)". Same with .upper() and uppercase.

With .casefold(), the docs explicitly state that it's meant for "caseless matching", and that it's "similar to lowercasing but more aggressive because it is intended to remove all case distinctions in a string".

Discussions

.casefold() vs. .lower()
Amy Tam is having issues with: I think the method .casefold() was not yet introduced, but I saw it when Craig introduced string methods with "help(str)." It seems like .casefo... More on teamtreehouse.com
🌐 teamtreehouse.com
1
March 13, 2019
casefold() vs lower()
lower is used for converting strings into lowercase, typically for display purposes. casefold is "stronger" because it will use additional rules for other characters. It's useful for comparing strings leniently. Look: >>> x = "ẞ ß" # Capital and lowercase sharp s >>> x.lower() 'ß ß' >>> x.casefold() 'ss ss' More on reddit.com
🌐 r/learnpython
19
30
October 12, 2024
Which string to lower case method to you use?
Latter. Reason: Did not even know the former existed till right now More on reddit.com
🌐 r/Python
30
0
May 22, 2022
Python lower() – How to Lowercase a Python String with the tolower Function Equivalent
Do we really need an article? I think the entirety of the tutorial could be written with fewer characters than the title. More on reddit.com
🌐 r/Python
6
0
November 4, 2022
🌐
GeeksforGeeks
geeksforgeeks.org › python › difference-between-casefold-and-lower-in-python
Difference between casefold() and lower() in Python - GeeksforGeeks
July 23, 2025 - Whereas casefold() method is an advanced version of lower() method, it converts the uppercase letter to lowercase including some special characters which are not specified in the ASCII table for example 'ß' which is a German letter and its ...
🌐
Python Morsels
pythonmorsels.com › uppercasing-and-lowercasing-in-python
Uppercasing and lowercasing in Python - Python Morsels
July 18, 2026 - The only difference between casefold and lower is that casefold normalizes a very small handful of non-English characters that don't have a simple lowercase equivalent. The classic example, and one of the few useful examples, is the German letter ...
🌐
Codingdeeply
codingdeeply.com › home › python casefold vs. lower: what’s better for string manipulation
Python Casefold vs. Lower: What's Better for String Manipulation - Codingdeeply
February 23, 2024 - Unicode normalization: .casefold() provides a more aggressive case conversion, handling special characters more effectively. Need help with when to use each method? Let’s make it clear…
🌐
TestDriven.io
testdriven.io › tips › f105d63d-3144-48c5-9e0a-c5b0f24e25b9
Tips and Tricks - Python - lower() vs. casefold() for string matching and converting to lowercase | TestDriven.io
Use .casfolde() instead of .lower() when you want to perform caseless operations when working with Unicode strings (for ASCII only strings they work the same) -- e.g., check if two strings are equal.
Find elsewhere
🌐
W3Schools
w3schools.com › python › ref_string_casefold.asp
Python String casefold() Method
This method is similar to the lower() method, but the casefold() method is stronger, more aggressive, meaning that it will convert more characters into lower case, and will find more matches when comparing two strings and both are converted ...
🌐
Sololearn
sololearn.com › en › Discuss › 2455515 › what-the-difference-between-lower-and-casefold
What the difference between .lower() and .casefold()?
Sololearn is the world's largest community of people learning to code. With over 25 programming courses, choose from thousands of topics to learn how to code, brush up your programming knowledge, upskill your technical ability, or stay informed about the latest trends.
🌐
Team Treehouse
teamtreehouse.com › community › casefold-vs-lower
.casefold() vs. .lower() (Example) | Treehouse Community
March 13, 2019 - Python · 2,227 Points · Posted ... methods with "help(str)." It seems like .casefold() allows caseless comparisons by more aggressively changing characters to the lowercase than .lower() does....
🌐
Skytowner
skytowner.com › explore › difference_between_casefold_and_lower_in_python
Difference between casefold() and lower() in Python
Python Tags · tocTable of Contents expand_more · Example mode_heat · Master the mathematics behind data science with 100+ top-tier guides Start your free 7-days trial now! str.casefold() is suited for caseless matching for unicode characters while str.lower() is suited for caseless matching ...
🌐
Scribd
scribd.com › document › 888817338 › Python-String-Methods-Casefold-vs-Lower
Casefold vs Lower in Python Explained | PDF | Letter Case | String (Computer Science)
The document explains the differences ... convert strings to lowercase, casefold() is more aggressive and suitable for case-insensitive comparisons, especially with non-ASCII characters....
🌐
YouTube
youtube.com › jakubication
Python casefold vs lower - YouTube
This video teaches about the casefold vs lower string methods in Python. casefold converts a string to a case-insensitive format, while lower simply lowercas...
Published: December 17, 2024
🌐
Python Pool
pythonpool.com › home › tutorials › python casefold(): case-insensitive and unicode-safe matching
Python casefold(): Case-Insensitive and Unicode-Safe Matching
July 13, 2026 - It is stronger than lower() because it is designed for Unicode text, not only simple ASCII lowercase conversion. Use casefold() when comparing user-facing text, usernames, search terms, tags, labels, or identifiers where capitalization should ...
🌐
Glarity
askai.glarity.app › search › What-is-the-difference-between--casefold----and--lower----in-Python
What is the difference between `casefold()` and `lower()` in Python? - Ask and Answer - Glarity
In this case, `casefold()` handles the character `ß` (sharp S) correctly by converting it to `ss`, whereas `lower()` does not make this conversion.
🌐
pythontutorials
pythontutorials.net › blog › lower-vs-casefold-in-string-matching-and-converting-to-lowercase
Python lower() vs casefold(): Key Differences for Case-Insensitive String Matching and Lowercase Conversion — pythontutorials.net
To choose between lower() and casefold(), consider their core differences: You need lowercase text for display or presentation (e.g., formatting user names as "john doe"). Working with ASCII-only text and simple normalization (no strict matching ...
🌐
Learn By Example
learnbyexample.org › python-string-casefold-method
Python String casefold() Method - Learn By Example
April 20, 2020 - The casefold() method returns a casefolded (lowercase but more aggressive) copy of the string.
🌐
Programmer
progr.interplanety.org › home › python: .lower() vs .casefold()
Python: .lower() vs .casefold() • Programmer - Interplanety
September 24, 2025 - .lower() – We use it to display text to the user. So, if we want to display lowercase text for the user to read, .lower() is our choice. .casefold() – We use it for comparison.
🌐
Educative
educative.io › answers › what-is-casefold-in-python
What is casefold() in Python?
casefold() is similar to the lower() method, but is stronger and helps with changing letters to lowercase in other languages.
🌐
Medium
medium.com › @yeaske › wait-there-is-casefold-in-python-9beb538c5a33
Mastering Python’s ‘casefold()’: A beginner’s guide | by Arun Suresh Kumar | Medium
May 14, 2024 - While the lower() method helps convert strings to lowercase, it is not always enough to handle certain Unicode characters and sequences. This is where Python's casefold() method comes handy.