chr()
Turn a Unicode codepoint into the single character at that position — the inverse of ord.
Common call
chr(65) # "A"
Returns
a str of length 1
Replaces
the "what character is codepoint N?" lookup
Watch out
range is 0..0x10FFFF; anything outside raises ValueError
chr(ii — A Unicode codepoint in the range 0..1_114_111 (0x10FFFF). Out-of-range raises ValueError.type: int · required)
→ str
Demo
Live evaluation
Try:
Inputs
iintcodepoint
Output
chr(65)
'A'
chr looks up a single codepoint and returns the character at that position. The Unicode range is 0..0x10FFFF (about 1.1 million codepoints); anything outside — negative or too large — raises ValueError. ord is the inverse operation.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| i | int | yes | A Unicode codepoint in the range 0..1_114_111 (0x10FFFF). Out-of-range raises ValueError. |
Return value
str — A one-character string whose Unicode codepoint is i.
Common patterns
Build a small alphabet
chr over a range gives you consecutive characters — cheap alphabet or digit table.
letters = [chr(i) for i in range(ord("a"), ord("z") + 1)]
Caesar cipher shift
Round-trip through codepoint, add a shift, wrap with modulo.
def shift(ch, k): base = ord("a") return chr(base + (ord(ch) - base + k) % 26)
Numeric to letter index (A=1)
One-based letter indexing — common in spreadsheet-column labels.
column_letter = chr(ord("A") + col - 1)
Examples
1. Basic letter
chr(65)
Returns
"A"2. Lowercase
chr(97)
Returns
"a"3. Digit character
chr(48)
Returns
"0"4. Greek letter
chr(937)
Returns
"Ω"5. Emoji
chr(128512)
Returns
"😀"6. Out of range
chr(2000000)
Returns
ValueError: chr() arg not in range(0x110000)Pitfalls
1. ValueError on out-of-range
The valid range is 0..0x10FFFF (inclusive). Negatives or values larger than 0x10FFFF raise ValueError — not a silent truncation.
Runtime error
chr(-1) chr(0x110000)
ValueError: chr() arg not in range(0x110000)
Guard the range
if 0 <= i <= 0x10FFFF: ch = chr(i)
safe lookup
2. Some codepoints are "lone surrogates"
The range 0xD800..0xDFFF holds UTF-16 surrogate halves. chr() will happily return them, but they are not valid Unicode characters — encoding them to bytes usually errors.
Encoding fails
s = chr(0xD800) s.encode("utf-8")
UnicodeEncodeError: surrogates not allowed
Stay outside the surrogate range
if not 0xD800 <= i <= 0xDFFF: ch = chr(i)
safe codepoint
3. Not the same as int → digit character
chr(5) is not "5" — codepoint 5 is a control character. To turn a digit 0..9 into its digit CHARACTER, use str(n) or chr(n + ord("0")).
Wrong output
chr(5)
"\x05" # a control character
Digit character
str(5) # or chr(ord("0") + 5)
"5"
When to use
Use it
- Building alphabets or digit tables from ranges
- Cipher / shift operations that work in codepoint space
- Producing specific characters from tables (emoji, symbols, control chars)
Reach for something else
- Digit codepoint → character → use str(n) instead
- Multi-character strings → chr returns exactly one character
- Bytes → use bytes([n]) for a single byte value
Notes
Complexity
O(1)
Return
str of length 1
CPython impl
Python/bltinmodule.c :: builtin_chr — thin wrapper around PyUnicode_FromOrdinal
Memory
Allocates one small string
Thread-safe
Yes — a pure computation
FAQ
chr(48) is the CHARACTER at codepoint 48 — the digit "0". str(48) is the decimal representation of the integer 48 — the string "48". They only coincide for 0..9 (and only when you add ord("0") to the digit).
History
1.0
chr() has been a builtin since Python 1.0.
3.0
Range expanded to full Unicode (0..0x10FFFF); no longer limited to 0..255.