Python First

Literals

2026-08-01

Abstract

Literals are constant values with clear and apparent values. You surely have no doubt about the value of 123? It is clearly not a variable… its value cannot vary, it is fixed, or constant (which is the reason some use the term ‘constant’ instead of the more appropriate ‘literal’).

In Python terminology, 123 is a literal having the value 123 with type of int. There are several other types of literals, each having their on syntax to distinguish them from other literals.

None

A lone, but special literal, is None, which is the only value that has type: NoneType. If you are familiar with SQL, you can think of None as roughly equivalent to NULL.

Some functions will return None under certain conditions. We cannot test if an expression is equal to None with the equality or inequality operators. Instead, we must use the identity comparison operators is and is not.

pyNone value and inspection

>> x = None
>> print(x is None)          #→ True
>> x = ""
>> print(x is not None)      #→ True

Some functions also has a default argument of None for a parameter. Such a parameter is then optional — you can pass an argument, or omit the argument (in which case None will be used automatically).

Boolean Literals

Not much to say here… there are only two boolean literals: False and True, and they have type bool (boolean). When you convert these literals to integers, False will become 0, and True will become 1.

pyBoolean literals True and False

>> print(True)                         #→ True
>> print(False)                        #→ False
>> print(int(False), int(True))        #→ 0 1

Because of implicit boolean conversion, we seldom have need for these literals.

pyBoolean expressions in if statements

>> a = True
>> if a == True: print("a is TRUE")    #→ a is TRUE
>> if a: print("a is TRUE")            #→ a is TRUE

The second statement unnecessarily used ‘if a == True:’, whereas ‘if a:’ worked just as well. The last version is more pythonic[1], if you care.

[1] From Wikipedia: “A common neologism in the Python community is pythonic, which has a wide range of meanings related to program style. "Pythonic" code may use Python idioms well, be natural or show fluency in the language, or conform with Python's minimalist philosophy and emphasis on readability. Code that is difficult to understand or reads like a rough transcription from another programming language is called unpythonic.”

Integer Literals

Numeric literal values without a decimal point are given the type int. The default numeric base is 10 (decimal 0…9), so ‘123’ means ‘one hundred and twenty three’. Python allows us to represent them in binary, octal, decimal (default) or hexadecimal. We can make literals more readable with embedded underscores.

Literal Syntax & Size

When we write literals, Python allows us to separate groups of digits with underscores (**_**). This is simply so that large numbers can be easier to read — they add no additional meaning. Python can handle huge integers, because Python supports arbitrary-precision arithmetic.

pyInteger literals

>> print(123**22)                 #→ 123 to the power 22
#→ 9504131829385633475328037226727697567232041929
>> print(123456789)               #→ 123456789
>> print(123_456_789)             #→ 123456789
>> print(1_2_3_4_5_6_7_8_9)       #→ 123456789

The last example is just obnoxious; there is never a good reason to put an underscore between every single digit — but Python does not care, it still sees it as the value 12345689. Readers of your code might just be annoyed if you overdo it. Line two, on the other hand, is a good example to follow.

Binary Literals

Integer literals can use base 2 (binary). For the digits to be treated as binary, the literal has to start with 0b. The decimal value 123, in binary, can thus be written as 0b1111011, or 0b_0111_1011 (leading zeros are allowed). To learn that 123 can be written in this binary value, you can use the built-in bin function.

pyBinary integer literals

>> print(bin(123))                #→ 0b1111011
>> print(0b1111011)               #→ 123
>> print(0b_0111_1011)            #→ 123

Not everybody needs to work with binary, so you could probably safely ignore binary. But understanding binary numbers can be an advantage.

Octal Literals

There are some applications and codes that are documented in octal (base 8), like the permissions of files and directories on Unix-like file systems. It is convenient because every octal digit (0-7) represents exactly three bits.

 0₈ ≡ 000₂   1₈ ≡ 001₂   2₈ ≡ 010₂   3₈ ≡ 011₂
 4₈ ≡ 100₂   5₈ ≡ 101₂   6₈ ≡ 110₂   7₈ ≡ 111₂

By memorising the above relationships, it becomes easy to convert from octal to binary, or from binary to octal — for those who care. Like binary, not everybody needs octal.

To write an literal integer in octal, you must start it with 0o. Like the other literals, you can separate digits with underscores. You can get the octal representation of any number using the oct function.

pyOctal an binary conversions

>> oct(123)                     #→ 0o173 ≡ 1×8²+7×8¹+3×8⁰ = 123
>> bin(0o_173)                  #→ 0b1111011
>> oct(0b_1_111_011)            #→ 0o173

Hexadecimal Literals

For base 16 (hexadecimal) literals, the prefix 0x is used. In hexadecimal, every one of the sixteen digits (0…9 A…F), represents exactly four bits when converted to binary. This again makes it easy to convert from hexadecimal to binary and vice versa.

 0₁₆ ≡ 0000₂   1₁₆ ≡ 0001₂   2₁₆ ≡ 0010₂   3₁₆ ≡ 0011₂
 4₁₆ ≡ 0100₂   5₁₆ ≡ 0101₂   6₁₆ ≡ 0110₂   7₁₆ ≡ 0111₂
 8₁₆ ≡ 1000₂   9₁₆ ≡ 1001₂   A₁₆ ≡ 1010₂   B₁₆ ≡ 1011₂
 C₁₆ ≡ 1100₂   D₁₆ ≡ 1101₂   E₁₆ ≡ 1110₂   F₁₆ ≡ 1111₂

The hex function can show the hexadecimal representation of an integer value.

pyHexadecimal and binary conversions

>> hex(123)             #→ 0x7b
>> 0x0000_007B          #→ 123
>> bin(0x7B)            #→ 0b1111011

And yes, not everybody might need to know or use hexadecimal values; but Unicode and other encoding values are often document with hexadecimal, to it may become more useful than you think — generally more useful than binary or octal, at least.

Floating-Point Literals

Sometimes integers do not fit the data we want to represent. For this purpose Python supplies the standard float type to represent numbers that can represents fractions in decimal notation (digits following a decimal point).

If a numeric literal contains a decimal point, and/or an e/E (for exponent), its type will be float, and not int or anything else. For those familiar with C, this maps to double, which is an IEEE-754 double-precision, 64-bit floating-point value.

pyTypes of floating point literals

>> type(.0)             #→ float
>> type(0.)             #→ float
>> type(0.0)            #→ float
>> type(1_234.456_7)    #→ float
>> type(1e234567)       #→ float
>> type(1_E_234_567)    #→ ERROR
>> type(1E234_567)      #→ float

Float Notation

Python supports two notations for floating point literals. The exponent is case-insensitive, so E will also work:

Underscores for digit grouping are allowed, but never before or after the e/E.

When a float is converted to str, implicitly or explicitly, Python will try to create as few significant digits as possible for the value to remain unambiguous. Because of IEEE-754, it can only display a maximum of 17 significant digits.

pyFloating point and fixed point notation

>> a = 123.456_789_012_345_678_900
>> b = 0.123_456_789_012_345_678_900
>> print(str(a))                     #→ 123.45678901234568
>> print(str(b))                     #→ 0.12345678901234568
>> print(a)                          #→ 123.45678901234568
>> print(b)                          #→ 0.12345678901234568

Whether explicitly converted with str, or implicitly by print, the result is the same.

Float Conversions

You cannot represent a floating point literal in hexadecimal notation in Python. You can convert it to hexadecimal with the hex function, or the float.hex() method. We can convert from a hexadecimal string back to float with float.fromhex().

pyFloat conversions

>> float.hex(1.23)
#→ '0x1.3ae147ae147aep+0'
>> float.fromhex('0x1.3ae147ae147aep+0')
#→ 1.23

We sometimes have need to convert a floating point value to an integer value. This will truncate any decimals. If you want to round a decimal to a certain number of places, you can use the built-in round function.

The Python Standard Library's math module provide many mathematical functions that operate on float values, and many return float values as results. It also provides the floor, ceil and trunc functions for other ways to convert to integers.

pyRounding and other float operations

>> import math          #← necessary.
>> num = 12.3456789
>> math.floor(num)      #→ 12
>> math.ceil(num)       #→ 13
>> math.int(num)        #→ 12
>> int(num)             #→ 12
>> round(num)           #→ 12
>> round(num, 2)        #→ 12.35
>> num = 12345.6789
>> round(num, -1)       #→ 12350.0
>> round(num, -2)       #→ 12300.0

As you can see, round takes an optional argument. If positive, it will round to the indicated number of decimals. When negative, it will round to the left; so -1, will round to the nearest unit of 10, and -2 to the nearest 100, and so on.

Float Formatting

Since it is something that may quickly bother your when you start experimenting with floating pointer numbers, is the number of decimal digits displayed. We can control that with formatting, which is quite a large topic, but here are a few examples:

pyFormatting floats

>> num = 1234.567890
>> print("num: |%.4f|" % num)               #→ |1234.5679|
>> print("num: |%10.4f|" % num)             #→ |  1234.5679|
>> print("num: |%-10.4f|" % num)            #→ |1234.5679  |
>> print("num: |{N:4f}|".format(N=num)      #→ |1234.5679|
>> print("num: |{N:10.4f}|".format(N=num))  #→ |  1234.5679|
>> print("num: |{N:<10.4f}|".format(N=num)) #→ |1234.5679  |
>> print("num: |{N:^10.4f}|".format(N=num)) #→ | 1234.5679 |
>> print(f"num: |{num:10.4f}|")             #→ |  1234.5679|
>> print(f"num: |{num:<10.4f}|")            #→ |1234.5679  |
>> print(f"num: |{num:^10.4f}|")            #→ | 1234.5679 |

The basic formatting syntax for floating point uses the f specifier for fixed point, and the e specifier for exponential notation.

     [align][width][.digits][f](## "Fixed point formatting specifier")    ←    fixed point.
     [align][width][.digits][e](## "Exponential notation formatting specifier")    ←    exponential notation.

The last three statements utilised f-strings, which is only available from Python 3.6 and later. It the version you probably should be using, since it is the most concise, flexible and less error-prone than the other more older formatting options.

The 10 in the formatting specifications above means that the total output width should be 10 characters wide, and if the value is smaller, to pad it with spaces on the left or right. The very last line also show how to centre output within a given output width.

String Literals

A sequence of characters stored in memory for the purpose of being a collective unit, is called a string, having type str. It would be strange for a programming language not to support string literals. Python has several ways to represent them.

Delimiters

String literals can use either ‘straight’ single quotes ('), or ‘straight’ double quotes (") as delimiters for sequences of characters. They have no difference in meaning, so which is used, is often a matter of preference. The quotes are not stored. A string can be empty: '', or "".

pyString literal forms

>> print("ABCDEF")             #→ ABCDEF
>> print('ABCDEF')             #→ ABCDEF
>> print(type("ABCDEF"))       #→ str
>> print(type('ABCDEF'))       #→ str
>> name = ''                   #← empty string.
>> name = ""                   #← empty string.

Strings delimited by these quotes cannot span lines — they must start and stop on the same line. You can use explicit statement continuation (backslash as last character on a line) inside a string literal.

pyInvalid string literals

>> print('                     #← ERROR
··    ABC')
>> print('\
·· ABC\
·· DEF')                       #→ ABCDEF

The trailing backslash and newline following it, is effectively deleted, so Python treats the last statement as:

pyResult of continuation

>> print('ABCDEF')

If we had leading spaces (indentation) before the ABC or DEF, that would become part of the string.

pyEffect of leading spaces

>> print('\
··    ABC\
··    DEF')                       #→    ABC   DEF

Not a very useful feature, so this will not be seen or used often, if at all.

Long Strings

Python also allows for long strings, which are sequence of characters delimited by three (triple) single quotes, or three double quotes. '''''', or """""". They are sometimes also called triple-quoted strings.

Long strings may contain embedded newlines (can span lines), but don't have to. Leading spaces (indentation) is significant.

pyLong/Tripple-quoted string literals

>> print("""ABCDEF""")           #→ ABCDEF
>> print('''ABCDEF''')           #→ ABCDEF
>> print('''ABC
··    DEF''')
#→ ABC
#→    DEF
>> print('''
·· ABC
·· DEF''')
#→
#→ ABC
#→ DEF
>> print('''\
·· ABC
·· DEF''')
#→ ABC
#→ DEF

The most common use for triple-quoted/long strings are as docstrings or documentation strings, as the first non-comment expression statement in a file (module), and as the very first statement inside classes and functions. These docstrings can be extracted with the standard pydoc module. It is also used by the built-in help function, and popup help in editors like VSCode.

pyDocstrings in functions

>> def myfunc1 ():
··     "Documentation for myfunc1"
··     return
>> def myfunc2 ():
··     """Documentation for myfunc2"""
··     return
>> def myfunc3 ():
··     """
··     Documentation for myfunc3
··     """
··     return
>> help(myfunc1)

The output of the last statement will be something like this:

Help on function myfunc1 in module __main__

myfunc1()
    Documentation for myfunc1

In our examples, only as a matter of consistency, we only use triple-quoted strings for docstrings; and in the form used with myfunc3.

Implicit Concatenation

String literals use any delimiters, can be implicitly concatenated if they are separated by only whitespace characters (tabs, newlines, spaces).

pyImplicit string literal concatenation

>> print("ABC"  'DEF')   #→ ABCDEF    ← concatenated.
>> print("ABC", 'DEF')   #→ ABC DEF   ← not concatenated.
>> print(
··    "ABC"
··    "DEF")             #→ ABCDEF    ← concatenated.

This rule applies to all string literals, even triple-quoted string literals.

pyMore implicit string literal concatenation

>> print("""ABC"""
··    '''DEF'''  "GHI")  #→ ABCDEFGHI

This implicit concatenation takes place during the initial phases of parsing statements. Following this phase, meaning is applied to the result, and will ‘see’ only one string literal.

Escape Sequences

Sometimes you may want to represent special characters inside a string that has no representation on you keyboard, or that your editor interprets (like TAB or CR).

Escape Character

Inside string literals, the backslash character (\) has special meaning. One consequence of this, is that you must write two backlashes to get one backslash stored. Following the backslash, can be one of several predefined characters, or an ASCII code code (compatible with corresponding Unicode codes).

Table: Escape Sequences

esc description
\NL Line continuation
\\ Single backslash
\' Useful inside '…'
\" Useful inside "…"
*** BEL bell character (code 7)
** BS backspace character (code 8)
** FF form feed character (code 12)
*** NL/LF (newline/linefeed) character (code 10)
** CR carriage return character (code 13)
** TAB/HT horizontal tab character (code 9)
** VT vertical tab character (code 11)
\ooo ooo ← octal character code
***hh hh ← hexadecimal character code
**hhhh hhhh ← hexadecimal 2-byte Unicode code
**hhhhhhhh hhhhhhhh hexadecimal 4-byte Unicode code
{name} Unicode character name

The escape sequences using character codes, must have leading zeros so that the value is either 2 digits (***), 4 digits () or 8 digits ().

pyCharacter code escapes

>> print("\101 \x41 \u0041 \U00000041")  #→ A A A A

Unicode Escapes

Other times, you may want to place Unicode characters in a string. If your Python file encoding is UTF-8, you can just paste Unicode characters from a Web page, for example. Or you can use the Unicode name: {name}.

An alternative to {}, is ‘hhhh’, where hhhh is a 4 digit hexadecimal value if the Unicode code is between 0000 and FFFF. For longer codes, you can use ‘hhhhhhhh’, which is long enough for any Unicode code.

pyUnicode characters

>> print("🐈 \N{CAT} \U0001F408")     #→ 🐈 🐈 🐈
>> print("🐍 \N{SNAKE} \U0001F40D")   #→ 🐍 🐍 🐍

Whether a Unicode character will display, depends on your terminal or other output device, and fonts. Sometimes font rendering systems will substitute characters for you, if the main font does not contain them. Browsers do that often.

Raw Strings

Sometimes it is inconvenient to deal with backslashes in strings. A good example is Windows path names:

pyNeed for raw strings

>> print( "C:\\Users\\me\\Documents\\filename.txt" )

Python allows a r/R prefix to string literals, which we then call raw string literals. The effect of the r/R, is that the backslash escape character will not be interpreted:

pyRaw string solution

>> print( r"C:\Users\me\Documents\filename.txt" )

Another situation where raw string literals are useful, is in the representation of regular expressions, by way of Python's standard re module. Regular expression syntax also use backslash as an escape character, but is first interpreted by the Python parses. So, to pass two backslashes (\\) to the regular expression code, you must type four (\\\\)… unless you use a raw string literal.

pyRaw strings for regular expressions

>> import re
>> pattern1 =  "\\d+\\s*\\w+"        #← without raw string.
>> pattern2 = r"\d+\s*\w+"           #← with raw string.
>> text = "Box of 12 apples."
>> print(re.findall(pattern1,text))  #→ ['12 apples']
>> print(re.findall(pattern2,text))  #→ ['12 apples']

There is one problem though… the last character in a raw string cannot be a backslash. That will cause a syntax error. We can use implicit concatenation in that case:

pyBackslash as last character solution

>> print( r"ABC\" )                  #← ERROR
>> print( r"ABC" "\\" )              #→ ABC\

The raw string literals prefix can also be applied to long strings.

Formatted Literals

Starting with Python 3.6, string literals may have an f/F prefix, in which case they are called formatted string literals, or just f-strings. The formatting syntax is the same ‘mini language’ employed by str.format().

Placeholders in a formatted string literal consists of paired curly braces ({}). Any expression may appear inside the curly braces, as long as the expression does not contain the same string delimiters, or any backslash.

pyBasic formatted string literals

>> print( f"--{"ABC"}--" )          #← ERROR
>> print( f"--{"ABC\n"}--" )        #← ERROR
>> print( f"--{'ABC'}--" )          #→ --ABC--
>> print( f'--{"ABC"}--' )          #→ --ABC--
>> text = "ABC"
>> print( f"--{text}--" )           #→ --ABC--

To prevent curly braces from being treated as placeholders in an f-string, they must appear twice. They do not have to be paired. The backslash escape character will not work: \{ or \}.

pyCurly braces in formatted string literals

>> print( f"{{2 * 3}}={2 * 3}" )    #→ {2 * 3}=6
>> print( f"{{2 * 3 ={2 * 3}" )     #→ {2 * 3 =6
>> print( f"2 * 3}} ={2 * 3}" )     #→ 2 * 3} =6

Note that the expression 2 * 3 was calculated and the result placed in the f-string, minus the placeholder curly braces. The expansion of an expression inside a string literal is often called string interpolation.

The basic syntax only requires an expression between the curly braces. Spaces around the expr part is ignored. A second variant allows a format specification following a colon (:).

     {expr}
     {expr:format}

What kind of formatting specifications are available, depends on the type of the expression. The result of the expression, is what gets formatted. The format can have an alignment prefix, but is only useful if the format includes an output width.

     format   ⇒   [fill][align][sign][#][0][width][,][**_**][.prec][type-spec]

Reminder: The available formatting options depend on the type of expression being formatted.

The type-spec part may be omitted, in which case the formatting will use the default specifier, depending on the actual type of the expression. Good convention suggests that you never omit the type-specifier.

pyMore formatting string literals

## Only ‹expr›ession part.
>> print(f"|{'Python'}|")        #→ Python
>> print(f"|{42}|")              #→ 42

## With alignment and width, without type-spec.
>> print(f"|{'Python':<10}|")    #→ |Python    |
>> print(f"|{42:>10}|")          #→ |        42|

## With precision for a float, without type-spec.
>> print(f"|{3.14159265:.3}|")   #→ |3.14|

## With type
>> print(f"|{42:b}|")            #→ |101010|
>> print(f"|{42:#b}|")           #→ |0b101010|
>> print(f"|{3.14159265:.3e}|")  #→ |3.142e+00|

The f-string string literals prefix can also be applied to long strings.

One can combined f-strings with raw strings, using any of the literal string prefixes fr or rf, in any combination of upper case or lower case.

Characters

Python does not have a type that represents a single character. A string containing one character, is a character. Some functions expects ‘a character’, which means they will only accept strings containing a single character.

You can get the ordinal value (Unicode code point) of a string containing one character, with the built-in ord function. It will not accept strings containing more than one character.

pyOrdinal values of some characters

print(ord("0"))                   #→ 48
print(ord("A"))                   #→ 65
print(ord("a"))                   #→ 97
print(ord("\N{SNAKE}"))           #→ 128013
print(hex(ord("\N{SNAKE}")))      #→ 0x1f40d

Given an ordinal value (Unicode code point), we can get a string containing one character from the built-in chr function.

pyCharacters from ordinal values

print(chr(48))                    #→ 0
print(chr(65))                    #→ A 
print(chr(97))                    #→ a
print(chr(128013))                #→ 🐍
print(chr(0x1f40d))               #→ 🐍

Copyright © 2026 Codi Matters