See also the old Python 2 quick reference.
#!/usr/bin/env python3
#!/usr/bin/env python3.11With one of the above shebangs as the first line of the script, most Unix/Linux systems will automatically pass the script to the latest installed version 3.x.x or 3.11.x Python interpreter when the script is run as a command. This also works on Windows if the script is passed to (or the typical script extension .py is associated with) the Python launcher py.exe.
a = 3 # Statements are usually separated by newlines print(a) # ... b = 'hi'; print(b) # (Non-compound) statements may be separated by semicolon c = 4; # and optionally terminated by semicolon # but using semicolons is discouraged (PEP 8) d = 2 * a + \ c # Any statement can be split across multiple lines # using backslash + newline (nothing allowed between the two) s = 'hel\ lo' # s = 'hel lo' (any indention is included in string) s = 'hel' \ 'lo' # s = 'hello' (adjacent string literals are concatenated) d = 2 * (a + # No backslash needed inside parentheses/brackets/... c) print('hel' # Prints 'hello' (adjacent string literals are concatenated; 'lo') # no backslash needed inside parentheses)
# Comments start with the '#' and end at the end of the same line, # so a comment spanning multiple lines must have '#' at the start # of each line. a = 3 # Here's a comment following some code b = a + \# ILLEGAL comment after backslash2 + # and backslash WON'T WORK after comment either -> \ 3 # Comment must be on last line when using backslashes """Another way to make a multiline comment is to put it inside a multiline string which is not assigned to anything.""" def f(): # Here's a docstring for this function (similar for classes, modules): """When a string is the first statement of a function (or class or module), it becomes that object's docstring, accessible via the __doc__ attribute. All lines traditionally have the same indentation, and those spaces become part of the string. """ return 3.14 print(f.__doc__) # Prints f's docstring (or None if none): 'When a string ...' help(f) # Prints information about f - including f's docstring
if len(mylist) > 0: # A compound statement contains a header sum = 0 # and a suite of statements with same indentation for x in mylist: # and possibly nested compound statements print(x) sum += x print(sum) else: # and possibly another header print('Empty list') # and its associated suite def func(x): # A compound statement cannot have an empty suite pass # but 'pass' can be used to do nothing if x < y: x = y; y = 0 # Single-line compound statement (discouraged) # (cannot contain nested compound statements)
import keyword keyword.kwlist # Returns the following list of "hard" Python keywords which cannot be # used as names of user-defined objects: # [ # 'False', # Bool value # 'None', # None value # 'True', # Bool value # 'and', # Logical operator # 'as', # Used with 'except', 'import', 'with', 'case' # 'assert', # Assertion # 'async', # Asynchronous coroutine function definition # 'await', # Asynchronous coroutine handling # 'break', # Loop control # 'class', # Class definition # 'continue', # Loop control # 'def', # Function definition # 'del', # Deletion of names, attributes (see delattr), and # # container items (see __delitem__) # 'elif', # Used with 'if' # 'else', # Used with 'if', 'for', 'try', 'while' # 'except', # Used with 'try' # 'finally', # Used with 'try' # 'for', # Looping, also in comprehensions and # # generator expressions # 'from', # Used with 'import', 'raise', 'yield' # 'global', # Name scope control # 'if', # Conditional execution/expression or condition in # # comprehension, generator expression, or 'case' # 'import', # Module importing # 'in', # Membership testing operator, or used with 'for' # 'is', # Identity testing operator # 'lambda', # Anonymous lambda function expression # 'nonlocal', # Name scope control # 'not', # Logical operator # 'or', # Logical operator # 'pass', # Empty statement # 'raise', # Exception raising # 'return', # Return from a function # 'try', # Exception handling # 'while', # Looping # 'with', # Context management # 'yield', # Generator function control # ] keyword.softkwlist # Returns the following list of "soft" Python keywords which may be # used as names of user-defined objects outside contexts where a # keyword is expected: # [ # '_', # Used with 'case' # 'case', # Used with 'match' # 'match', # Pattern matching # ]
# Expression list t = 4, a + 1, 'hi' # Right-hand side expression list becomes tuple (4, 2, 'hi') # (assuming a = 1) a, (b, c) = 3, (4, 5) # Multiple assignments a=3, b=4, c=5 using expression lists # (all right-hand expressions are evaluated before any assignments) a, (b, c) = [3, (4, 5)] # Some alternatives equivalent to above; [] could also be () [a, (b, c)] = 3, (4, 5) # ... a, *b, c = 1, 2, 3, 4 # Starred target (iterable unpacking); assigns a=1, b=[2,3], c=4 a, *b, c = range(5) # Assigns a=0, b=[1,2,3], c=4 10, # Trailing comma is illegal/mandatory/optional if 0/1/more items [4, a + 1, 'hi'] # List created from expression list {4, a + 1, 'hi'} # Set created from expression list f(4, a + 1, 'hi') # Function call using expression list as argument list f(*range(2), **{'a':5}) # Iterable unpacking; same as f(0, 1, a=5)
Python provides syntax for annotating names (variables and functions) with their intended types, but Python itself does not enforce these types (and never will, according to PEP 484). IDEs and other tools (e.g. mypy) may use the type hints to do checking and assist developers in various ways.
See Types for more information on available types.
# Define f as a function that takes an integer and a string and returns a string def f(n: int, s: str) -> str: r: str = n * s return r MyList = list[tuple[str, float]] # Defines MyList as an alias for a list of tuples # of string and float a: MyList = [('A', 3), ('B', 4.1)] # Defines 'a' to have type MyList and assigns a # valid object matching that type b: tuple[int, ...] = (1, 2, 3) # Defines 'b' to be a tuple of 0 or more integers # and assigns a valid object matching that type d: dict[str, int | None] = {'A': 4, 'B': None} # Defines 'd' to be a dict that maps from # string to either integer or None
# Import more type hinting support from 'typing' module from typing import TypeAlias, TypeVar, Any, Generic # Import 'Sequence' from abstract base class module from collections.abc import Sequence MyType: TypeAlias = tuple[str, Any] # Defines MyType as an explicit alias for a tuple # of string and any type T = TypeVar('T', int, MyType) # Defines T to be a type variable that is # constrained to being either an int or a MyType # and can be used to define generic functions and # classes # Define a generic function 'get' that takes an int and a sequence of T and returns a T def get(i: int, s: Sequence[T]) -> T: return s[i] # Define a generic class 'G' that works with any of T's possible types (i.e. int or MyType) class G(Generic[T]): def __init__(self, s: Sequence[T]) -> None: self.s: Sequence[T] = s def get(self, i: int) -> T: return self.s[i] x: list[MyType] = [('A', 4), ('B', 'oo')] # Defines 'x' to be a list of MyType and # assigns a valid object matching that type get(0, x) # Calls function 'get' with arguments matching # its parameter type hints; returns ('A', 4) G(x).get(0) # Creates an instance of class G using x as the # constructor argument (T is implicitly MyType) # and calls method 'get'; returns ('A', 4) G[int]([4,5,6]).get(0) # Creates an instance of class G (with T # explicitly set to int) using a list of ints # as the constructor argument, calls method # 'get', and returns 4
i = -2 # Assigns an int (infinite range and precision) type(i) # Returns class int isinstance(i, int) # Returns True int('20') # Returns 20 (an int) int('20', 16) # Returns 32 (second arg is base, 16 means hex) i += 0xA + 0o12 + 0b10 # i is now 20 (-2 + 10 + 10 + 2); this is hex + octal + binary012# ILLEGAL! (non-zero decimal numbers may not start with a zero - # avoids confusion with obsolete octal format) i.bit_length() # Returns 5 (minimum number of bits needed to represent 20) (5).bit_length() # Returns 3 (5.bit_length() would fail because 5. means 5.0) 1_000_000 + 0b_1111_1111# Returns 1000255 (underscores improve readability)
x = -3.4 # Assigns a float (range: sys.float_info.min to sys.float_info.max) type(x) # Returns class float isinstance(x, float) # Returns True float(3) # Returns 3.0 float('2.5e6') # Returns 2500000.0 float('inf') # Returns positive infinity (greater than sys.float_info.max) float('-inf') # Returns negative infinity (less than sys.float_info.min) float('nan') # Returns the "not a number" (NaN) error value 0 * float('inf') # Returns float('nan') import math # Imports math module float('inf') == math.inf # Returns True float('-inf') == -math.inf # Returns True math.isinf(float('-inf')) # Returns True math.isnan(float('nan')) # Returns True math.nan == math.nan # Returns False; NaN is unequal to everything, incl. itself math.sin(math.pi/2) # Returns 1.0 math.sqrt(2) # Returns 1.4142135623730951 1. + .2 + 3.4e-2 # Returns 1.234 (1. means 1.0, .2 means 0.2) 0.000_000_001 # Returns 1e-9 (underscores improve readability) 0.1 + 0.2 == 0.3 # Returns False because these values cannot be represented exactly # in floating point binary; use the decimal.Decimal type if exact # representations of (base-10) decimal values are needed, e.g. if # D = decimal.Decimal then D('0.1') + D('0.2') == D('0.3') returns # True math.isclose(0.1 + 0.2, 0.3) # Returns True because 0.1 + 0.2 is (very) close to 0.3
c = 1+2j # Assigns a complex (pair of floats) type(c) # Returns class complex isinstance(c, complex) # Returns True c.real # 1.0 c.imag # 2.0c.real = 3# ILLEGAL! Raises AttributeError exception (complex is immutable) c.conjugate() # Returns (1-2j) complex(1, 2) # Returns (1+2j) complex('1+2j') # Returns (1+2j) complex(1+2j, 10j) # Returns (-9+2j) because 10j is multiplied by 1j and becomes -10 complex('infj') # Same as complex(0, float('inf')) complex('-infj') # Same as complex(0, float('-inf')) complex('inf-infj') # Same as complex(float('inf'), float('-inf')) complex('nanj') # Same as complex(0, float('nan')) import cmath # Imports cmath module (complex math) complex('infj') == cmath.infj # Returns True complex('-infj') == -cmath.infj # Returns True cmath.isinf(complex('-infj')) # Returns True cmath.isnan(complex('nanj')) # Returns True abs(3+4j) # Returns 5.0 (magnitude) cmath.phase(3+4j) # Returns 0.9272952180016122 (approx. 53 degrees in radians) cmath.polar(3+4j) # Returns (5.0, 0.9272952180016122) cmath.rect(2, cmath.pi/4) # Returns (1.4142135623730951+1.4142135623730951j) cmath.sqrt(-1) # Returns 1j 0.1j + 0.2j == 0.3j # Returns False (see float type above for details) cmath.isclose(0.1j + 0.2j, 0.3j) # Returns True because 0.1j + 0.2j is close to 0.3j
b = True # Assigns a bool (True or False) type(b) # Returns class bool isinstance(b, bool) # Returns True bool(0) # Returns False for 0 (else True) bool('') # Returns False for empty sequence type (else True) bool(None) # Returns False int(True) # Returns 1 int(False) # Returns 0 3 + True # Returns 4 False * 5 # Returns 0
x = None # Assigns null object (nothing, unassigned argument/return value) type(x) # Returns class with name 'NoneType'; None is the only instance of # this class isinstance(x, type(None)) # Returns True bool(x) # Returns False
sl = slice(3) # Assigns a slice object equivalent to the :3 in a[:3] (supports # same parameters as range(), except negative start/stop values are # counted from end); more under classes type(sl) # Returns class slice isinstance(sl, slice) # Returns True print(sl) # Prints 'slice(None, 3, None)' 'hello'[sl] # Returns 'hel' (same as 'hello'[:3]) sl.start, sl.stop, sl.step # Returns (None, 3, None) sl.indices(len('hello')) # Returns (0, 3, 1) (range()-style (start, stop, step) args) sl.indices(len('hi')) # Returns (0, 2, 1) (range is reduced to fit given length) sl = slice(-2, None, -1)# Assigns a slice object equivalent to the -2::-1 in a[-2::-1] 'hello'[sl] # Returns 'lleh' (same as 'hello'[-2::-1]) sl.indices(len('hello'))# Returns (3, -1, -1) (here, stop == None for slice() maps to # stop == -1 for range())
e = Ellipsis # Assigns Ellipsis object (intended for extended slice syntax) type(e) # Returns class with name 'ellipsis'; Ellipsis is the only instance # of this class isinstance(e, type(Ellipsis)) # Returns True bool(e) # Returns True e2 = ... # Assigns Ellipsis object using alternative name '...' e2 is e # Returns True (there is only one Ellipsis object)
n = NotImplemented # Assigns NotImplemented object (returned by methods such as # __add__ when they can't handle the provided argument type; the # interpreter will then try something else such as calling __radd__ # on the other operand) type(n) # Returns class with name 'NotImplementedType'; NotImplemented is # the only instance of this class isinstance(n, type(NotImplemented)) # Returns True bool(n) # Returns True
o = object() # Assigns a featureless object; object is the base of all # classes/types (about classes/types and objects) type(o) # Returns class object isinstance(o, object) # Returns True isinstance(10, object) # Returns True (int is a subclass of object)
T = type('MyT', (), {}) # Assigns a type object; all classes/types are instances of type # (about classes/types and objects) type(T) # Returns class type isinstance(T, type) # Returns True class T2: pass # Assigns a type object using a class statement (normal approach) type(T2) # Returns class type
The following is a list of attributes (properties and methods) provided by instances of the basic types int, float, complex, bool, slice. (Some general object attributes and low-level attributes are omitted from this list).
Show attributes below:o.__abs__() # Special method implementing abs(o); # applies to int,float,complex,bool o.__add__(o2) # Special method implementing o + o2; # applies to int,float,complex,bool o.__and__(o2) # Special method implementing o & o2; # applies to int,bool o.__bool__() # Special method implementing bool(o); # applies to int,float,complex,bool o.__ceil__() # Special method implementing math.ceil(o); # applies to int,float,bool o.__complex__() # Special method implementing complex(o); # applies to complex o.__divmod__(o2) # Special method # applies to int,float,bool o.__eq__(o2) # Special method # applies to int,float,complex,bool,slice o.__float__() # Special method # applies to int,float,bool o.__floor__() # Special method # applies to int,float,bool o.__floordiv__(o2) # Special method # applies to int,float,bool o.__ge__(o2) # Special method # applies to int,float,bool,slice o.__getformat__(t) # TBD # applies to float o.__getnewargs__() # TBD (pickle protocol) # applies to int,float,complex,bool o.__gt__(o2) # Special method # applies to int,float,bool,slice o.__index__() # Special method # applies to int,bool o.__int__() # Special method # applies to int,float,bool o.__invert__() # Special method # applies to int,bool o.__le__(o2) # Special method # applies to int,float,bool,slice o.__lshift__(o2) # Special method # applies to int,bool o.__lt__(o2) # Special method # applies to int,float,bool,slice o.__mod__(o2) # Special method # applies to int,float,bool o.__mul__(o2) # Special method # applies to int,float,complex,bool o.__ne__(o2) # Special method # applies to int,float,complex,bool,slice o.__neg__() # Special method # applies to int,float,complex,bool o.__or__(o2) # Special method # applies to int,bool o.__pos__() # Special method # applies to int,float,complex,bool o.__pow__(o2) # Special method # applies to int,float,complex,bool o.__radd__(o2) # Special method # applies to int,float,complex,bool o.__rand__(o2) # Special method # applies to int,bool o.__rdivmod__(o2) # Special method # applies to int,float,bool o.__rfloordiv__(o2) # Special method # applies to int,float,bool o.__rlshift__(o2) # Special method # applies to int,bool o.__rmod__(o2) # Special method # applies to int,float,bool o.__rmul__(o2) # Special method # applies to int,float,complex,bool o.__ror__(o2) # Special method # applies to int,bool o.__round__() # Special method # applies to int,float,bool o.__rpow__(o2) # Special method # applies to int,float,complex,bool o.__rrshift__(o2) # Special method # applies to int,bool o.__rshift__(o2) # Special method # applies to int,bool o.__rsub__(o2) # Special method # applies to int,float,complex,bool o.__rtruediv__(o2) # Special method # applies to int,float,complex,bool o.__rxor__(o2) # Special method # applies to int,bool o.__sub__(o2) # Special method # applies to int,float,complex,bool o.__truediv__(o2) # Special method # applies to int,float,complex,bool o.__trunc__() # Special method # applies to int,float,bool o.__xor__(o2) # Special method # applies to int,bool
o.as_integer_ratio() # Returns 2-tuple of integers whose ratio is equal to o; # (-1.5).as_integer_ratio() returns (-3,2); 0.1.as_integer_ratio() # returns<PHONE_NUMBER>896397,<PHONE_NUMBER>8963968) # (but decimal.Decimal('0.1').as_integer_ratio() returns (1, 10)); # applies to int,float,bool o.bit_count() # Returns number of 1-bits in o; (10).bit_count() returns 2; # applies to int,bool o.bit_length() # Returns minimum number of bits (disregarding sign) needed to # represent o; (10).bit_length() returns 4; # applies to int,bool o.conjugate() # Returns complex conjugate of o; (1+2j).conjugate() returns (1-2j); # applies to int,float,complex,bool o.denominator # Is 1 (unless o is a fractions.Fraction); # applies to int,bool o.from_bytes(b,e,signed=s) # Class method; returns object of same class as o converted # from bytes object b with byte order e ('big', 'little', # sys.byteorder) in two's complement if s is True (default False); # int.from_bytes(b'\xfe\xff','little',signed=True) returns -2; # applies to int,bool o.fromhex(s) # Class method; returns float value converted from hex number in # string s; float.fromhex(' ff.8 ') returns 255.5; # float.fromhex('0x1p10') returns 1024.0; # applies to float o.hex() # Returns hex string representing float o (in '0x#p#' format); # 255.0.hex() returns '0x1.fe00000000000p+7'; # applies to float o.imag # Imaginary part of o (which is 0 if o is not complex); # (3+4j).imag returns 4; (3).imag returns 0; 4j.imag returns 4; # applies to int,float,complex,bool o.indices(n) # Returns tuple of integers (start, stop, step) which can be passed # to range() to get a sequence of indices corresponding to applying # slice o to a sequence of length n; # ii = slice(None,None,-1).indices(5) makes ii (4,-1,-1), and # list(range(*ii)) returns [4,3,2,1,0]; # applies to slice o.is_integer() # Returns True if o is integral; 3.0.is_integer() returns True; # applies to float o.numerator # Is int(o) (unless o is a fractions.Fraction); # applies to int,bool o.real # Real part of o (which is o or int(o) if o is not complex); # (3+4j).real returns 3; (3).real returns 3; 4j.real returns 0; # applies to int,float,complex,bool o.start # Read-only start value of slice o; slice(2,5).start returns 2; # applies to slice o.step # Read-only step value of slice o; slice(5,2,-1).step returns -1; # applies to slice o.stop # Read-only stop value of slice o; slice(5).stop returns 5; # applies to slice o.to_bytes(n,e,signed=s)# Returns n-byte bytes object representing o with byte order e # ('big', 'little', sys.byteorder) and in two's complement if s is # True (default False); raises OverflowError if o is out of range # (-2).to_bytes(2,'little',signed=True) returns b'\xfe\xff'; # applies to int,bool
# Container type detection import collections.abc # Imports abstract base class module isinstance(o, collections.abc.Container)# Returns True if o is container object (e.g. 'hi')
import collections.abc # Imports abstract base class module isinstance(o, collections.abc.Sequence) # Returns True if o is sequence object (e.g. 'hi')
s1 = 'Say "hi"\n\'ho\'' # Assigns a string (immutable): Say "hi"(newline)'ho' s2 = "Say 'hi'\n\"ho\"" # Same as above, but with swapped single- and double-quotes # (Single-quotes allow embedded unescaped double-quotes, and vice # versa, otherwise no difference in behavior) s3 = """Say "hi" 'ho'""" # Same as s1 above; triple-quotes allow embedded unescaped newlines # (usually used for docstrings) s4 = '''Say 'hi' "ho"''' # Same as s2 above (but triple single-quotes are not often used) s5 = r'\n\'' # Raw string of length 4: backslash, 'n', backslash, single-quote; # backslashes are taken literally, but still escape quotes; often # used for regular expressions s6 = r"""\\ """ # Raw triple-quoted string of length 3: 2 backslashes and a newline # (see s3 and s5 above) s7 = '\xC6\u0E01\U0001F60E' # Assigns a string containing 3 Unicode characters; len(s7) is 3 s8 = r'\u0E01\n' # \u escapes are not interpreted in raw strings; len(s8) is 8 # characters) s9 = f'{2+5:03d}\n' # Formatted string literal: '007'(newline) s10 = fr'{2+5}\n' # Formatted raw string literal: '7', backslash, 'n' (see s5 and s9 # above) s11 = rf'{2+5}\n' # Same as s10 aboveu'hi'# Same as 'hi'; Python 3 ignores the u prefix (but ur'' and uf'' # are illegal) '\a\b\f\n\r\t\v\'\"\\' # Same as '\x07\x08\x0C\x0A\x0D\x09\x0B\x27\x22\x5C' '\N{bel}\N{backspace}\N{form feed}\N{line feed}\N{carriage return}\ \N{horizontal tabulation}\N{vertical tabulation}\N{apostrophe}\N{quotation mark}\ \N{reverse solidus}' # Same string as above (note that '\N{bel}' == '\x07', but # '\N{bell}' == '\U0001F514') s = ('hel' # Adjacent string literals are concatenated (s = 'hello'); "lo") # useful for splitting string literals and commenting each part # (see statement boundaries for other ways of breaking strings) type(s) # Returns class str isinstance(s, str) # Returns True len(s) # Returns 5 'e' in s # Returns True s[0] # Returns 'h's[0] = 'a'# ILLEGAL! Raises TypeError exception because string is immutable s[-1] # Returns 'o' s[1:3] # Returns 'el' (general slice syntax is [start:stop:step] with # default values (if omitted) start=0, stop=end, step=1) s[-2:] # Returns 'lo' s[:-1] # Returns 'hell' s[::-1] # Returns 'olleh' s + ' there' # Returns 'hello there' s * 2 # Returns 'hellohello' str(4.1) # Returns '4.1'
a1 = [3, 'hello'] # Assigns a list (mutable) type(a1) # Returns class list isinstance(a1, list) # Returns True len(a1) # Returns 2 'hello' in a1 # Returns True a1[-1] # Returns 'hello' a1[0] = [4] # Assigns list [4] to first item of list a1 a1.append('bye') # a1 is now [[4], 'hello', 'bye'] a1.extend([10, 11]) # a1 is now [[4], 'hello', 'bye', 10, 11] a1[-2:] = [9] # a1 is now [[4], 'hello', 'bye', 9] del a1[-2:] # a1 is now [[4], 'hello'] a2 = a1 # a2 now points to same list as a1 # (changes to a1 items affect a2 items) a2 = a1[:] # a2 is now a shallow copy of a1 # (changes to 1st level of a1 don't affect a2) # (use a2 = copy.deepcopy(a1) to make a complete copy) list('hello') # Returns ['h', 'e', 'l', 'l', 'o']
t = (3, 'hello') # Assigns a tuple (immutable) t = 3, 'hello' # Same as above but using unenclosed expression list type(t) # Returns class tuple () # Returns () (empty tuple) (4,) # Returns (4,) (single-item tuple) (4) # Returns 4 (int, not tuple) isinstance(t, tuple) # Returns True len(t) # Returns 2 'hello' in t # Returns True t[-1] # Returns 'hello't[-1] = 'a'# ILLEGAL! Raises TypeError exception because tuple is immutable tuple('hello') # Returns ('h', 'e', 'l', 'l', 'o') t2 = (4, []) # Although tuples are immutable, they may contain mutable items t2[-1].append(5) # t2 is now (4, [5])
import collections NT = collections.namedtuple('Mynamedtuple', 'x,y,z') # Assigns a new named tuple type; # namedtuple itself is not a type but a function that makes a type type(NT) # Returns class type nt = NT(4, 5, z=6) # Assigns a named tuple of type NT (immutable; like tuple, but # allows items to be accessed by name) type(nt) # Returns class with name 'Mynamedtuple' isinstance(nt, NT) # Returns True nt.x # Returns 4 (unlike tuple) nt[-1] # Returns 6 (like tuple) 5 in nt # Returns True (like tuple) NT._make([6,7,8]) # Same as NT(6, 7, 8) or NT(*[6, 7, 8]) NT2 = collections.namedtuple('NT2', ('a','b','c'), defaults=(8,9)) # Assigns a new named # tuple type with defaults for the last 2 items nt2 = NT2(7) # Assigns a named tuple of type NT2; values must be provided for # all items that don't have defaults nt2._asdict() # Returns {'a':7, 'b':8, 'c':9}
b1 = bytes(3) # Assigns a bytes object b'\x00\x00\x00' (immutable) b2 = bytes([65, 66, 67]) # Assigns a bytes object b'ABC' from a list (each value must be # in the range 0-255) b3 = bytes('\u0E01\u0E2E', 'utf_8') # Assigns a bytes object b'\xe0\xb8\x81\xe0\xb8\xae' # from a string using the specified encoding b4 = b'hi\n' + br'\n' # Assigns a bytes object b'hi\n\\n' ('hi' + newline + backslash # + 'n', see string type above) from ascii strings list(b1) # Returns [0, 0, 0] list(b2) # Returns [65, 66, 67] list(b3) # Returns [224, 184, 129, 224, 184, 174] list(b4) # Returns [104, 105, 10, 92, 110] print(b2) # Prints "b'ABC'" print(b2[0]) # Prints '65' type(b1) # Returns class bytes isinstance(b1, bytes) # Returns True len(b1) # Returns 3 len(b3) # Returns 6 b1 += b2 # b1 is now b'\x00\x00\x00ABC' (b1 is reassigned, not mutated) b2.decode() # Returns string 'ABC' 'ABC'.encode() # Returns b'ABC'
b1 = bytearray(2) # Assigns a bytearray (same as bytes, but mutable) # containing 2 null bytes b2 = bytearray([65, 66, 67]) # Assigns a bytearray from a list # (each value must be in the range 0-255) b3 = bytearray('\u0E01\u0E2E', 'utf_8') # Assigns a bytearray from a string using the # specified encoding b4 = bytearray(b'ABC') # Assigns a bytearray from a bytes object (b4 == b2) list(b1) # Returns [0, 0] list(b2) # Returns [65, 66, 67] list(b3) # Returns [224, 184, 129, 224, 184, 174] print(b2) # Prints "bytearray(b'ABC')" print(b2[0]) # Prints '65' type(b1) # Returns class bytearray isinstance(b1, bytearray) # Returns True len(b1) # Returns 2 b1[0] = 72 # b1 now contains 72, 0 b1[1:] = b'ey' # b1 now contains 72, 101, 121 b1 += b2 # b1 now contains 72, 101, 121, 65, 66, 67 print(b1) # Prints "bytearray(b'HeyABC')"
b = bytes([4,5,6,7,8,9,254,255]) # Assigns a bytes object from a list m = memoryview(b) # Assigns a memoryview referencing object b type(m) # Returns class memoryview isinstance(m, memoryview) # Returns True m.readonly # Returns True (because the referenced object b is immutable) m.tolist() # Returns [4, 5, 6, 7, 8, 9, 254, 255] m[-1] # Returns 255 (last element) m[1:4] # Returns a new memoryview referencing b[1:4] m2 = m.cast('b', [2,4]) # New 2D memoryview referencing b (1-byte signed elements) m2.tolist() # Returns [[4, 5, 6, 7], [8, 9, -2, -1]] m2[1,2] # Returns -2 m3 = m.cast('H') # New memoryview referencing b (2-byte unsigned elements) m3.tolist() # Returns [1284, 1798, 2312, 65534] if platform is little-endian, # corresponding to [0x0504, 0x0706, 0x0908, 0xfffe] m4 = m.cast('i') # New memoryview referencing b (4-byte signed elements) m4.tolist() # Returns [117835012, -128760] if platform is little-endian ba = bytearray(b'hello')# Assigns a bytearray from a bytes object m5 = memoryview(ba) # Assigns a memoryview referencing object ba m5.readonly # Returns False (because the referenced object ba is mutable) m5[1] = ord('u') # ba is now bytearray(b'hullo')
r = range(4) # Assigns a range object (immutable) representing 0, 1, 2, 3 (from # 0 to 4 (4 excluded)) without actually storing this sequence type(r) # Returns class range print(r) # Prints 'range(0, 4)'; r is an unexpanded range object print(list(r)) # Prints '[0, 1, 2, 3]'; list(r) expands r to a list print(tuple(r)) # Prints '(0, 1, 2, 3)'; tuple(r) expands r to a tuple isinstance(r, range) # Returns True len(r) # Returns 4 r[-1] # Returns 3 range(2, 5) # Returns range object representing sequence 2, 3, 4 (from 2 to 5 # (5 excluded) with step 1) range(1, -2, -1) # Returns range object representing sequence 1, 0, -1 (from 1 to -2 # (-2 excluded) with step -1)
u = {3, 'hello'} # Assigns a set (mutable; unordered unique items) type(u) # Returns class set set() # Returns empty set {} # Returns empty dict, not set! isinstance(u, set) # Returns True len(u) # Returns 2 'hello' in u # Returns True u.add(10) # u is now {'hello', 10, 3} (undefined order) u.remove(10) # u is now {'hello', 3} u.remove(10) # Raises KeyError exception (no such item) u.discard(3) # u is now {'hello'} u.discard(3) # u is unchanged (did not contain 3) set('hello') # Returns {'l', 'o', 'h', 'e'} (only one 'l')
w = frozenset((3, 'hi')) # Assigns a frozenset (like a set, but immutable, so can be # used as a dictionary key or element of a set) type(w) # Returns class frozenset isinstance(w, frozenset) # Returns True
d = {'a':10, 'b':5} # Assigns a dictionary (mutable ordered mapping (preserves # insertion order); unique keys; was unordered until Python 3.7) type(d) # Returns class dict {} # Returns {} (empty dict, not set) isinstance(d, dict) # Returns True len(d) # Returns 2 'a' in d # Returns True d['a'] = 11 # d is now {'a': 11, 'b': 5} dk = d.keys() # Assigns a live view of d's keys type(dk) # Returns class with name 'dict_keys' list(dk) # Returns ['a', 'b'] dv = d.values() # Assigns a live view of d's values type(dv) # Returns class with name 'dict_values' list(dv) # Returns [11, 5] di = d.items() # Assigns a live view of d's items type(di) # Returns class with name 'dict_items' list(di) # Returns [('a', 11), ('b', 5)] del d['a'] # d is now {'b': 5} list(dk) # Returns ['b'] list(dv) # Returns [5] list(di) # Returns [('b', 5)] dict((('a',10),('b',5))) # Returns {'a': 10, 'b': 5} dict(a=10, b=5) # Returns {'a': 10, 'b': 5}
import collections dd = collections.defaultdict(int, {'a': 3}) # Assigns a defaultdict (same as dict, but the # first arg is called with no args to provide the default value for # nonexistent keys; here, int() returns the default value 0) type(dd) # Returns class collections.defaultdict isinstance(dd, collections.defaultdict) # Returns True dd['a'] # Returns 3 dd['b'] # Returns 0 (because that's what int() returns); # dd is now defaultdict(int, {'a': 3, 'b': 0}) dd['c'] += 1 # dd is now defaultdict(int, {'a': 3, 'b': 0, 'c': 1})
import collections od = collections.OrderedDict([('a',10), ('b',11), ('c',12)]) # Assigns an OrderedDict (like # dict but has more functionality and different performance) type(od) # Returns class collections.OrderedDict isinstance(od, collections.OrderedDict) # Returns True od.move_to_end('a') # od is now OrderedDict([('b',11), ('c',12), ('a',10)]) od.move_to_end('a',last=False) # od is now OrderedDict([('a',10), ('b',11), ('c',12)]) od.popitem() # Returns ('c',12); od is now OrderedDict([('a',10), ('b',11)]) od.popitem(last=False) # Returns ('a',10); od is now OrderedDict([('b',11)])
import collections c = collections.Counter('abaab') # Assigns a Counter (like a dict, but the values are # counts for the keys, i.e. {'a': 3, 'b': 2}) type(c) # Returns class collections.Counter isinstance(c, collections.Counter) # Returns True c['a'] # Returns 3 c['x'] # Returns 0 c['c'] += 2 # c is now Counter({'a': 3, 'b': 2, 'c': 2}) c['b'] -= 6 # c is now Counter({'a': 3, 'b': -4, 'c': 2}) c.update(['a', 'c']) # c is now Counter({'a': 4, 'b': -4, 'c': 3}) c.update({'a': 5}) # c is now Counter({'a': 9, 'b': -4, 'c': 3}) c.most_common(2) # Returns [('a', 9), ('c', 3)] (2 most common items ordered with # most common first) c.most_common() # Returns [('a', 9), ('c', 3), ('b', -4)] (all items ordered with # most common first) c + collections.Counter({'a':-1, 'b':4}) # Returns Counter({'a': 8, 'c': 3}); items with # non-positive counts are discarded after arithmetic/set operations # on Counter objects
import collections q = collections.deque() # Assigns a deque (a bit like list but with faster adding/removing # of items at both ends and slower indexing in the middle) type(q) # Returns class collections.deque isinstance(q, collections.deque) # Returns True q = collections.deque((3, 'hi'), maxlen=4) # Assigns a new deque containing items 3 and # 'hi' and restricted to max 4 items q.append('right') # q is now deque([3, 'hi', 'right']) q.appendleft('left') # q is now deque(['left', 3, 'hi', 'right']) q.append('R') # q is now deque([3, 'hi', 'right', 'R']); 'left' got pushed out # due to maxlen=4 q.appendleft('left') # q is now deque(['left', 3, 'hi', 'right']); 'R' got pushed out # due to maxlen=4 if q: # If q is not empty... q.pop() # Returns 'right'; q is now deque(['left', 3, 'hi']) q.popleft() # Returns 'left'; q is now deque([3, 'hi']) q.extend([4,5,6]) # q is now deque(['hi', 4, 5, 6]); 3 got pushed out due to maxlen=4 q.extendleft([2,1]) # q is now deque([1, 2, 'hi', 4]); 5 and 6 got pushed out q.rotate(-1) # q is now deque([2, 'hi', 4, 1]); items rotated 1 place left
The following is a list of attributes (properties and methods) provided by instances of the container types str, list, tuple, (types produced by) collections.namedtuple, bytes, bytearray, memoryview, range, set, frozenset, dict, collections.defaultdict, collections.OrderedDict, collections.Counter, collections.deque. (Some general object attributes and low-level attributes are omitted from this list).
Show attributes below:o.__add__(o2) # Special method implementing o + o2 (concatenation); 'hi' + 'ho' # returns 'hiho'; for Counter the counts of equal keys are added # (and then items with non-positive counts are removed); # applies to str,list,tuple,namedtuple,bytes,bytearray,Counter, # deque o.__alloc__() # Returns number of bytes allocated to o; # bytearray(b'hi').__alloc__() returns 3; # applies to bytearray o.__and__(o2) # Implements o & o2 (intersection); {1,'a',3} & {'a',3,4} returns # {'a',3}; for Counter the intersection applies to the keys and the # smallest count is chosen for equal keys (and then items with non- # positive counts are removed); # applies to set,frozenset,Counter o.__bool__() # TBD # applies to range o.__bytes__() # TBD # applies to bytes o.__class_getitem__(x) # TBD # applies to list,tuple,namedtuple,set,frozenset,dict,defaultdict, # OrderedDict,Counter,deque o.__contains__(x) # Implements x in o (membership test); 'b' in 'abc' returns True; # applies to str,list,tuple,namedtuple,bytes,bytearray,range,set, # frozenset,dict,defaultdict,OrderedDict,Counter,deque o.__copy__() # Implements copy.copy(o) (shallow copy); # applies to defaultdict,deque o.__delitem__(x) # Implements del o[x] (item deletion); if o = [4,5] then del o[0] # makes o [5]; o.__delitem__(slice(x,y,z)) implements del o[x:y:z]; # applies to list,bytearray,dict,defaultdict,OrderedDict,Counter, # deque o.__enter__() # TBD # applies to memoryview o.__eq__(o2) # Implements o == o2; # applies to str,list,tuple,namedtuple,bytes,bytearray,memoryview, # range,set,frozenset,dict,defaultdict,OrderedDict,Counter,deque o.__exit__() # TBD # applies to memoryview o.__ge__(o2) # Implements o >= o2; # applies to str,list,tuple,namedtuple,bytes,bytearray,set, # frozenset,Counter,deque o.__getitem__(x) # Implements o[x]; # o.__getitem__(slice(x,y,z)) implements o[x:y:z]; # applies to str,list,tuple,namedtuple,bytes,bytearray,memoryview, # range,dict,defaultdict,OrderedDict,Counter,deque o.__getnewargs__() # TBD (pickle protocol) # applies to str,tuple,namedtuple,bytes o.__gt__(o2) # Implements o > o2; # applies to str,list,tuple,namedtuple,bytes,bytearray,set, # frozenset,Counter,deque o.__iadd__(o2) # Implements o += o2 (in-place concatenation); if o = [1,2] then # o += [3,4] makes o [1,2,3,4]; # applies to list,bytearray,Counter,deque o.__iand__(o2) # Implements o &= o2 (in-place intersection); # applies to set,Counter o.__imul__(x) # Implements o *= x (in-place repetition); if o = [1,2] then o *= 3 # makes o [1,2,1,2,1,2]; # applies to list,bytearray,deque o.__ior__(o2) # Implements o |= o2 (in-place union); # applies to set,dict,defaultdict,OrderedDict,Counter o.__isub__(o2) # Implements o -= o2 (in-place difference); # applies to set,Counter o.__iter__() # Implements iter(o); returns an iterator for iterable o; # applies to str,list,tuple,namedtuple,bytes,bytearray,memoryview, # range,set,frozenset,dict,defaultdict,OrderedDict,Counter,deque o.__ixor__(o2) # Implements o ^= o2 (in-place symmetric difference); # applies to set o.__le__(o2) # Implements o <= o2; # applies to str,list,tuple,namedtuple,bytes,bytearray,set, # frozenset,Counter,deque o.__len__() # Implements len(o) (item count); len([5,6]) returns 2; # applies to str,list,tuple,namedtuple,bytes,bytearray,memoryview, # range,set,frozenset,dict,defaultdict,OrderedDict,Counter,deque o.__lt__(o2) # Implements o < o2; # applies to str,list,tuple,namedtuple,bytes,bytearray,set, # frozenset,Counter,deque o.__match_args__ # TBD # applies to namedtuple o.__missing__(x) # Implements o[x] if x is not one of o's keys; returns the default # value for a missing key; # applies to defaultdict,Counter o.__mod__(x) # Implements o % x (formatting); '%-3s%03u' % ('hi', 9) returns # 'hi 009'; # applies to str,bytes,bytearray o.__mul__(x) # Implements o * x (repetition); [1,2] * 3 returns [1,2,1,2,1,2]; # applies to str,list,tuple,namedtuple,bytes,bytearray,deque o.__ne__(o2) # Implements o != o2; # applies to str,list,tuple,namedtuple,bytes,bytearray,memoryview, # range,set,frozenset,dict,defaultdict,OrderedDict,Counter,deque o.__neg__() # Implements -o (negation); for Counter each count is negated (and # then items with non-positive counts are removed); # applies to Counter o.__or__(o2) # Implements o | o2 (union); # {1,'a',3} | {'a',3,4} returns {1,'a',3,4}; # {'x':2,'y':3} | {'x':1,'z':4} returns {'x':1,'y':3,'z':4}; # for Counter the union applies to the keys and the largest count # is chosen for equal keys (and then items with non-positive counts # are removed); # applies to set,frozenset,dict,defaultdict,OrderedDict,Counter o.__pos__() # Implements +o; for Counter this removes items with non-positive # counts; # applies to Counter o.__rand__(o2) # Implements o2 & o (reverse intersection); # applies to set,frozenset o.__reversed__() # Implements reversed(o); returns a reverse order iterator for o; # applies to list,range,dict,defaultdict,OrderedDict,Counter,deque o.__rmod__(o2) # Implements o2 % o (reverse formatting); # applies to str,bytes,bytearray o.__rmul__(x) # Implements x * o (reverse repetition); 3 * [1,2] returns # [1,2,1,2,1,2]; # applies to str,list,tuple,namedtuple,bytes,bytearray,deque o.__ror__(o2) # Implements o2 | o (reverse union); # applies to set,frozenset,dict,defaultdict,OrderedDict,Counter o.__rsub__(o2) # Implements o2 - o (reverse difference); # applies to set,frozenset o.__rxor__(o2) # Implements o2 ^ o (reverse symmetric difference); # applies to set,frozenset o.__setitem__(x, v) # Implements o[x] = v; # o.__setitem__(slice(x,y,z), v) implements o[x:y:z] = v; # applies to list,bytearray,memoryview,dict,defaultdict, # OrderedDict,Counter,deque o.__sub__(o2) # Implements o - o2 (difference); {1,'a',3} - {'a',3,4} returns {1}; # for Counter the counts of equal keys are subtracted (and then # items with non-positive counts are removed); # applies to set,frozenset,Counter o.__xor__(o2) # Implements o ^ o2 (symmetric difference); {1,'a',3} ^ {'a',3,4} # returns {1,4}; # applies to set,frozenset
o._asdict() # Returns a dict mapping o's field names to values; if o = # namedtuple('NT', 'x,y')(3,4) then o._asdict() returns # {'x':3, 'y':4}; # applies to namedtuple o._field_defaults # Dict mapping o's field names to default values; if o = # namedtuple('NT', 'x,y,z', defaults=(2,3)) then o._field_defaults # is {'y':2, 'z':3}; # applies to namedtuple o._fields # Tuple of o's field names; if o = namedtuple('NT', 'x,y') then # o._fields is ('x', 'y'); # applies to namedtuple o._make(o2) # Class method; returns a new object of the same class as o and # initializes the new object with the values in o2; if o = # namedtuple('NT', 'x,y') then o._make([3,4]) returns a new named # tuple o(x=3, y=4) - same as o(*[3,4]); # applies to namedtuple o._replace(**kwargs) # Returns a copy of o with new values for the specified fields; # if NT = namedtuple('NT', 'x,y,z') and o = NT(3,4,5) then # o._replace(x=6,z=2) returns a new named tuple NT(6,4,2); # applies to namedtuple o.add(x) # Puts x into o; if o = {3} then o.add(5) makes o {3,5}; # applies to set o.append(x) # Inserts x at end of o; if o = [3] then o.append(5) makes o [3,5]; # applies to list,bytearray,deque o.appendleft(x) # Inserts x at start of o; if o = deque([3]) then o.appendleft(5) # makes o deque([5, 3]); # applies to deque o.c_contiguous # Read-only bool which is True if o's memory layout is contiguous # and C-style (last index of array increments fastest); always True # if o is 1-dimensional and contiguous; if o = # memoryview(b'abcd').cast('B',[2,2]) then o.c_contiguous is True; # applies to memoryview o.capitalize() # Returns a copy of o with first character capitalized; # 'hi ho'.capitalize() returns 'Hi ho'; # applies to str,bytes,bytearray o.casefold() # Returns a copy of o suitable for caseless comparisons; # 'Heiß'.casefold() returns 'heiss'; # applies to str o.cast(f,s) # Returns a new memoryview of o's buffer with format f and shape s; # if o = memoryview(bytes([1,2,3,255])) then # o.cast('B', [2,2]).tolist() returns [[1,2], [3,255]] (unsigned), # o.cast('h').tolist() returns [513, -253] (16-bit signed int), # o.cast('i').tolist() returns [-16580095] (32-bit signed int) # (last 2 examples assume little-endian platform); # applies to memoryview o.center(w,c) # Returns a copy of o centered in a string of length w filled with # c (space if no c); returns an unmodified copy if len(o) >= w; # 'hi'.center(5,'*') returns '**hi*'; # applies to str,bytes,bytearray o.clear() # Makes o empty; if o = {3:9,5:25} then o.clear() makes o {}; # applies to list,bytearray,set,dict,defaultdict,OrderedDict, # Counter,deque o.contiguous # Read-only bool which is True if o's memory layout is contiguous # (the numpy module supports non-contiguous arrays); # applies to memoryview o.copy() # Returns a shallow copy of o (similar to copy.copy(o) but doesn't # call o.__copy__()); if o = {4:[5]} then o.copy() returns a new # {4:[5]} referencing the same list [5] as o; # applies to list,bytearray,set,frozenset,dict,defaultdict, # OrderedDict,Counter,deque o.count(x) # Returns count of non-overlapping occurrences of x in o; # 'hohohoho'.count('hoho') returns 2; # applies to str,list,tuple,namedtuple,bytes,bytearray,range,deque o.count(x,a,b) # Returns count of non-overlapping occurrences of x in o[a:b]; # a,b are optional; 'hohohoho'.count('hoho',1) returns 1; # 'hohohoho'.count('hoho',0,7) returns 1; # applies to str,bytes,bytearray o.decode(enc,err) # Returns string equal to o decoded using encoding enc # (default 'utf-8') and error scheme err (default 'strict') # b'A\xc7\xbf'.decode() returns 'A\u01ff'; # b'A\xc0'.decode() raises UnicodeDecodeError; # b'A\xc0'.decode('utf-8','ignore') returns 'A'; # b'A\xc0'.decode('utf-8','replace') returns 'A\ufffd'; # applies to bytes,bytearray o.default_factory # Function called by o to get default value for nonexistent keys; # if o = defaultdict(int) then o.default_factory returns class int, # o[5] returns 0 (from int()) and makes o defaultdict(int, {5:0}), # o.default_factory = str makes o defaultdict(str, {5:0}), and o[6] # returns '' (str()) and makes o defaultdict(str, {5:0, 6:''}); # applies to defaultdict o.difference(o2,...) # Same as o - set(o2) - ... (but doesn't call o.__sub__()); # {1,2,3,4}.difference({2,6},[7,3]) returns {1,4}; # applies to set,frozenset o.difference_update(o2,...) # Same as o -= set(o2) | ... (but doesn't call o.__isub__()); # if o = {1,2,3,4} then o.difference_update({2,6},[7,3]) makes # o {1,4}; # applies to set o.discard(x) # Removes item x from o; does nothing if x is not in o; # if o = {3,5} then o.discard(5) makes o {3}; # applies to set o.elements() # Returns an iterator which returns each item of o repeated # according to its count (items with non-positive counts are # excluded); if o = Counter({'a': 4, 'b': -4, 'c': 3}) or o = # Counter('acaacca') then ''.join(o.elements()) returns 'aaaaccc'; # applies to Counter o.encode(enc,err) # Returns bytes object equal to o encoded using encoding enc # (default 'utf-8') and error scheme err (default 'strict') # 'A\u01ff'.encode() returns b'A\xc7\xbf'; # 'A\u0080'.encode('ascii') raises UnicodeEncodeError; # 'A\u0080'.encode('ascii','ignore') returns b'A'; # 'A\u0080'.encode('ascii','replace') returns b'A?'; # 'A\u0080'.encode('ascii','xmlcharrefreplace') returns b'A€'; # 'A\u0080'.encode('ascii','backslashreplace') returns b'A\\x80'; # applies to str o.endswith(x,a,b) # Returns True if o[a:b] ends with x (or with an item in tuple x); # 'abc'.endswith(('bc','z')) returns True; # applies to str,bytes,bytearray o.expandtabs(n) # Returns a copy of o with tab characters replaced by up to n # spaces (enough spaces to reach the next tab column); # '\ta\tbc\td'.expandtabs(3) returns ' a bc d'; # applies to str,bytes,bytearray o.extend(o2) # Same as o += o2 (but doesn't call o.__iadd__()); if o = [3,5] # then o.extend([1,2]) makes o [3,5,1,2]; # applies to list,bytearray,deque o.extendleft(o2) # Inserts all items from o2 (in reverse order) at start of o; if o # = deque([3,5]) then o.extendleft([1,2]) makes o deque([2,1,3,5]); # applies to deque o.f_contiguous # Read-only bool which is True if o's memory layout is contiguous # and Fortran-style (first index of array increments fastest; the # numpy module supports Fortran-style arrays); # always True if o is 1-dimensional and contiguous; if o = # memoryview(b'abcd').cast('B',[2,2]) then o.f_contiguous is False; # applies to memoryview o.find(o2,a,b) # Returns index of first occurrence of substring o2 in o[a:b] (a=0, # b=len(o) if not given), or -1 if none found; # 'abab'.find('ab') returns 0; 'abab'.find('ab',1,3) returns -1; # applies to str,bytes,bytearray o.format(...) # Returns a string representing the arguments formatted according # to the directives in o; see string formatting; # '{:03d}{:4.1f}{x:>2.1s}'.format(6,7,x='AB') returns '006 7.0 A'; # applies to str o.format_map(o2) # Returns a string representing the values of dict o2 formatted # according to the directives in o (which refer to o2's keys); # '{x:03d}{y:4.1f}'.format_map(dict(x=6,y=7)) returns '006 7.0'; # applies to str o.fromhex(s) # Class method; returns object of same class as o containing bytes # corresponding to pairs of hex digits in string s; # bytes.fromhex('4142 43 0a') returns b'ABC\n'; # applies to bytes,bytearray o.fromkeys(o2,x) # Class method; returns object of same class as o containing all # items of sequence o2 as keys with all values equal to x (default # None); dict.fromkeys(('a','b'), 5) returns {'a':5, 'b':5}; # applies to dict,defaultdict,OrderedDict o.get(k,d) # Returns o[k], or d if k is not in o (d is None if omitted); # {'a':6}.get('a',5) returns 6, {'a':6}.get('b',5) returns 5, and # {'a':6}.get('b') returns None; # applies to dict,defaultdict,OrderedDict,Counter o.hex(sep,n) # Returns string containing pairs of hex digits corresponding to # bytes in o, with separator sep inserted every n bytes from the # right (or left if n < 0); raises ValueError if sep is given and # not a single character; sep == '' and n == 1 if not given; # b'ABC\n'.hex() returns '4142430a'; # b'ABC'.hex(':') returns '41:42:43' # b'ABC'.hex(':',2) returns '41:4243' # b'ABC'.hex(':',-2) returns '4142:43' # applies to bytes,bytearray,memoryview o.index(x) # Returns index of first occurrence of item x in o; raises # ValueError if x is not in o; # for str,bytes,bytearray: x may be a substring of o; # [4,5,4].index(4) returns 0; 'abab'.index('ba') returns 1; # applies to str,list,tuple,namedtuple,bytes,bytearray,range,deque o.index(x,a,b) # Returns index of first occurrence of item x in o[a:b] (a=0, # b=len(o) if not given); raises ValueError if x is not in o[a:b]; # for str,bytes,bytearray: x may be a substring of o; # [4,5,4].index(4) returns 0; 'abab'.index('ab',1) returns 2; # applies to str,list,tuple,namedtuple,bytes,bytearray,deque o.insert(i,x) # Inserts item x in o at index i; same as o[i:i] = [x]; # if o = [4,5,6] then o.insert(2,'a') makes o [4,5,'a',6]; # applies to list,bytearray,deque o.intersection(o2,...) # Same as o & set(o2) & ... (but doesn't call o.__and__()); # {1,2,3,4}.intersection({3,2,6},[7,3]) returns {3}; # applies to set,frozenset o.intersection_update(o2,...) # Same as o &= set(o2) & ... (but doesn't call o.__iand__()); # if o = {1,2,3,4} then o.intersection_update({2,6},[7,3]) # makes o {3}; # applies to set o.isalnum() # Returns True if o is not empty and contains only alphanumeric # characters (alphabetic or numeric characters); # for characters 'Aªข': 'A\u00aa\u0e02'.isalnum() returns True; # for characters '2๒': '2\u0e52'.isalnum() returns True; # for character '²': '\u00b2'.isalnum() returns True; # for character '½': '\u00bd'.isalnum() returns True; # applies to str,bytes,bytearray o.isalpha() # Returns True if o is not empty and contains only alphabetic # characters; # for characters 'Aªข': 'A\u00aa\u0e02'.isalpha() returns True; # '2'.isalpha() returns False; '@'.isalpha() returns False; # applies to str,bytes,bytearray o.isascii() # Returns True if o does not contain non-ASCII characters # (characters above '\x7F'); '\x00\x7f'.isascii() returns True; # '\x80'.isascii() returns False; ''.isascii() returns True; # applies to str,bytes,bytearray o.isdecimal() # Returns True if o is not empty and contains only decimal # characters (a subset of digits); # for characters '2๒': '2\u0e52'.isdecimal() returns True; # for character '²': '\u00b2'.isdecimal() returns False; # for character '½': '\u00bd'.isdecimal() returns False; # applies to str o.isdigit() # Returns True if o is not empty and contains only digits # (a subset of numeric characters); # for characters '2๒': '2\u0e52'.isdigit() returns True; # for character '²': '\u00b2'.isdigit() returns True; # for character '½': '\u00bd'.isdigit() returns False; # applies to str,bytes,bytearray o.isdisjoint(o2) # Returns True if o and o2 have no common items; # {1,3}.isdisjoint([4,2]) returns True; {'A'}.isdisjoint('ABC') # returns False; # applies to set,frozenset o.isidentifier() # Returns True if o fulfills the rules for being a valid Python # identifier; 'aBc_2'.isidentifier() returns True; # applies to str o.islower() # Returns True if o contains at least 1 cased character and all # cased characters are lowercase; 'ver2.0'.islower() returns True; # applies to str,bytes,bytearray o.isnumeric() # Returns True if o is not empty and contains only numeric # characters; # for characters '2๒': '2\u0e52'.isnumeric() returns True; # for character '²': '\u00b2'.isnumeric() returns True; # for character '½': '\u00bd'.isnumeric() returns True; # applies to str o.isprintable() # Returns True if o doesn't contain non-printable characters # (separators other than the space character are considered non- # printable in this context); 'hi ho'.isprintable() returns True; # '\n'.isprintable() returns False; ''.isprintable() returns True; # applies to str o.isspace() # Returns True if o is not empty and contains only whitespace # characters; ' \t\n\r\f\v'.isspace() returns True; # applies to str,bytes,bytearray o.issubset(o2) # Same as o <= o2 (but doesn't call o.__le__()); # {4,2}.issubset({1,2,3,4}) returns True; # {5,2}.issubset({1,2,3,4}) returns False; # applies to set,frozenset o.issuperset(o2) # Same as o >= o2 (but doesn't call o.__ge__()); # {1,2,3,4}.issuperset({4,2}) returns True; # {1,2,3,4}.issuperset({5,2}) returns False; # applies to set,frozenset o.istitle() # Returns True if o contains at least 1 uppercase character, no # uppercase character follows a cased character, and any lowercase # character follows a cased character; # '2B|Not 2B'.istitle() returns True; # applies to str,bytes,bytearray o.isupper() # Returns True if o contains at least 1 cased character and all # cased characters are uppercase; 'VER2.0'.isupper() returns True; # applies to str,bytes,bytearray o.items() # Returns a live view of o's items; if o = {4:5,6:7} and v = # o.items() then list(v) returns [(4,5),(6,7)] and v will follow # changes to o; # applies to dict,defaultdict,OrderedDict,Counter o.itemsize # Read-only size in bytes of each item in o; if o = # memoryview(array.array('h', [4,5,6])) then o.itemsize is 2; # applies to memoryview o.join(o2) # Returns the object obtained by concatenating all items of o2 # using o as separator; '/'.join('abc') returns 'a/b/c'; # b'=='.join([b'x',b'42']) returns b'x==42'; # applies to str,bytes,bytearray o.keys() # Returns a live view of o's keys; if o = {4:5,6:7} and v = o.keys() # then list(v) returns [4,6] and v will follow changes to o; # applies to dict,defaultdict,OrderedDict,Counter o.ljust(w,c) # Returns a copy of o left-justified in a string of length w filled # with c (space if no c); returns an unmodified copy if len(o) >= w; # 'hi'.ljust(5,'*') returns 'hi***'; # applies to str,bytes,bytearray o.lower() # Returns a copy of o with all uppercase characters converted to # lowercase; '2B|Not 2B'.lower() returns '2b|not 2b'; # applies to str,bytes,bytearray o.lstrip(s) # Returns a copy of o with first characters removed if present in # string s (whitespace if no s); 'abcd'.lstrip('dba') returns 'cd'; # ' \t\na '.lstrip() returns 'a '; # applies to str,bytes,bytearray o.maketrans(d) # Static method; returns dict d converted to a dict for use with # o.translate(); str.maketrans({'A':'B'}) returns {65:'B'}; # applies to str o.maketrans(f,t) # Static method; returns a table for use with o.translate() mapping # each character in f to the corresponding character in t; # str.maketrans('AB', 'CD') returns {65:67, 66:68}; # bytes.maketrans(b'AB', b'CD') returns a 256-byte bytes object # with each byte value equal to its index, except the bytes at # indices 65 and 66 have values 67 and 68 instead of 65 and 66; # applies to str,bytes,bytearray o.maketrans(f,t,tnone) # Static method; returns a dict for use with o.translate() mapping # each character in f to the corresponding character in t, and each # character in tnone to None; # str.maketrans('AB', 'CD', 'E') returns {65:67, 66:68, 69:None}; # applies to str o.maxlen # Read-only maximum length of o (None if o has no maximum length); # deque().maxlen returns None; deque(maxlen=5).maxlen returns 5; # applies to deque o.most_common(n) # Returns a list of o's items and counts sorted by decreasing count; # if n is given, the list only includes the n items with largest # counts; if o = Counter({'a': 2, 'b': -4, 'c': 3}) then # o.most_common() returns [('c', 3), ('a', 2), ('b', -4)], and # o.most_common(1) returns [('c', 3)]; # applies to Counter o.move_to_end(key,last) # Moves key to start (if last=False) or end (if last=True) of o; # default is end if last is not given; # if o = OrderedDict(a=4,b=5,c=6) then: # o.move_to_end(key='b') makes o OrderedDict(a=4,c=6,b=5); # o.move_to_end('b',True) makes o OrderedDict(a=4,c=6,b=5); # o.move_to_end('b',last=False) makes o OrderedDict(b=5,a=4,c=6); # applies to OrderedDict o.nbytes # Read-only number of bytes in o (excl. gaps between non-contiguous # parts); if o = memoryview(array.array('h', [1,2,3])) then # o.nbytes is 6 (on platforms where a C short is 2 bytes); # applies to memoryview o.ndim # Read-only number of dimensions in o; if o = # memoryview(b'abcd').cast('B',[1,4]) then o.ndim is 2 (1 row in # the 1st dimension and 4 columns in the 2nd); # applies to memoryview o.obj # Read-only reference to o's underlying object; if b = bytearray() # and o = memoryview(b) then o.obj is b; # applies to memoryview o.partition(o2) # Returns (o[:i],o[i],o[i+1:]) where i is index of first occurrence # of o2 in o, or (o[:],type(o)(),type(o)()) if o2 is not found in o; # 'abba'.partition('b') returns ('a','b','ba'); # b'abba'.partition(b'x') returns (b'abba',b'',b''); # applies to str,bytes,bytearray o.pop() # Removes and returns last item in o (arbitrary item if o is a set); # raises KeyError (set) or IndexError (others) if no item; # if o = [4,5,6] then o.pop() returns 6 and makes o [4,5]; # applies to list,bytearray,set,deque o.pop(i) # Removes and returns item o[i]; raises IndexError (list, bytearray) # or KeyError (others) if no item; if o = [4,5,6] then o.pop(1) # returns 5 and makes o [4,6]; if o = {4:9,5:3,6:9} then o.pop(5) # returns 3 and makes o {4:9,6:9}; # applies to list,bytearray,dict,defaultdict,OrderedDict,Counter o.popitem() # Removes and returns last added (key, o[key]) pair; raises # KeyError if o is empty; if o = {3:9,5:25} then o.popitem() makes # o {3:9} and returns (5,25); # applies to dict,defaultdict,OrderedDict,Counter o.popleft() # Removes and returns first item in o; raises IndexError if no item; # if o = deque([3,5]) then o.popleft() returns 3 and makes o # deque([5]); # applies to deque o.readonly # Read-only bool which is True if o is read-only; # if o = memoryview(b'abc') then o.readonly is True; # if o = memoryview(bytearray(3)) then o.readonly is False; # applies to memoryview o.release() # Releases o's underlying object so it can no longer be accessed # via o; if o = memoryview(b'abc') and o.release() is called then # o.obj raises ValueError, and so does o[0], but o.release() may be # called any number of times; # applies to memoryview o.remove(x) # Removes item x from o; raises ValueError (KeyError for set) if x # is not in o; if o = [3,5] then o.remove(5) makes o [3]; # applies to list,bytearray,set,deque o.removeprefix(o2) # Returns a copy of o with o2 removed if present at start of o; # 'abcd'.removeprefix('ab') returns 'cd'; # 'abcd'.removeprefix('bc') returns 'abcd'; # applies to str,bytes,bytearray o.removesuffix(o2) # Returns a copy of o with o2 removed if present at end of o; # 'abcd'.removesuffix('cd') returns 'ab'; # 'abcd'.removesuffix('bc') returns 'abcd'; # applies to str,bytes,bytearray o.replace(s1,s2,n) # Returns a copy of o with first n (or all if no n) occurrences of # s1 replaced with s2; 'boohoo'.replace('oo','*') returns 'b*h*'; # 'boohoo'.replace('oo','*',1) returns 'b*hoo'; # applies to str,bytes,bytearray o.reverse() # Reverses the items of o; same as o[::-1] = o; # if o = [4,5,6] then o.reverse() makes o [6,5,4]; # applies to list,bytearray,deque o.rfind(o2,a,b) # Same as o.find(), except last occurrence is chosen; # 'abab'.rfind('ab') returns 2; 'abab'.rfind('ab',1,3) returns -1; # applies to str,bytes,bytearray o.rindex(x,a,b) # Same as o.index(), except last occurrence is chosen; # 'abab'.rindex('ab') returns 2; 'abab'.rindex('ab',0,3) returns 0; # applies to str,bytes,bytearray o.rjust(w,c) # Returns a copy of o right-justified in a string of length w # filled with c (space if no c); returns an unmodified copy if # len(o) >= w; 'hi'.rjust(5,'*') returns '***hi'; # applies to str,bytes,bytearray o.rotate(n) # Rotates o's items n places to the right (left if n < 0; 1 place # right if no n); if o = deque([1,2,3,4]) then o.rotate() makes o # deque([4,1,2,3], o.rotate(-1) makes o deque([1,2,3,4]) again, and # o.rotate(3) makes o deque([2,3,4,1]); # applies to deque o.rpartition(o2) # Returns (o[:i],o[i],o[i+1:]) where i is index of last occurrence # of o2 in o, or (type(o)(),type(o)(),o[:]) if o2 is not found in o; # 'abba'.rpartition('b') returns ('ab','b','a'); # b'abba'.rpartition(b'x') returns (b'',b'',b'abba'); # applies to str,bytes,bytearray o.rsplit(sep,maxsplit) # Same as o.split(), except splitting is done from the right when # maxsplit is given; # 'fooboohoo'.rsplit('oo', 1) returns ['foobooh','']; # applies to str,bytes,bytearray o.rstrip(s) # Returns a copy of o with last characters removed if present in # string s (whitespace if no s); 'abcd'.rstrip('cda') returns 'ab'; # ' a \t\n'.rstrip() returns ' a'; # applies to str,bytes,bytearray o.setdefault(k,d) # Returns o[k] if it exists, otherwise sets o[k] = d (None if no d) # and returns this value; # if o = {2:6} then o.setdefault(2,8) returns 6 (o is unchanged), # o.setdefault(3,8) makes o {2:6, 3:8} and returns 8, and # o.setdefault(4) makes o {2:6, 3:8, 4:None} and returns None; # applies to dict,defaultdict,OrderedDict,Counter o.shape # Read-only tuple containing the number of items in o's dimensions; # if o = memoryview(b'abcd').cast('B',[1,4]) then o.shape is (1,4); # applies to memoryview o.sort(key=kf,reverse=r)# Sorts the items of o using key function kf (kf(x) returns a # comparison key for each item x, and is lambda x:x if not given); # two items x and y are always compared using kf(x).__lt__(kf(y)); # if kf is a class with a suitable __lt__ method, kf(x) creates a # new instance of this class as the comparison key for item x; # sort order is reversed if r is True (r is False if not given); # if o = [-6,5,10] then o.sort(reverse=True) makes o [10,5,-6], and # o.sort(key=abs) makes o [5,-6,10]; # applies to list o.split(sep,maxsplit) # Returns a list of parts of o split at each occurrence of sep, or # at each sequence of whitespace if sep is omitted or None; # if maxsplit is given and not -1, only maxsplit splits are done; # ' hi ho '.split() returns ['hi','ho']; ' '.split() returns []; # ' hi ho '.split(' ') returns ['','hi','','ho','']; # 'fooboohoo'.split('oo', 1) returns ['f','boohoo']; # ''.split(' ') returns ['']; # applies to str,bytes,bytearray o.splitlines(keepends) # Returns a list of lines in o, splitting at any type of newline, # and discarding newlines if keepends is omitted or False; # 'hi\nho\r'.splitlines() returns ['hi','ho']; # 'hi\r\nho\n\r'.splitlines(True) returns ['hi\r\n','ho\n','\r']; # 'hi\nho'.splitlines(keepends=True) returns ['hi\n','ho']; # '\n'.splitlines() returns ['']; ''.splitlines() returns []; # applies to str,bytes,bytearray o.start # Read-only start value of range o; range(10).start returns 0; # applies to range o.startswith(x,a,b) # Returns True if o[a:b] starts with x (or with an item in tuple x); # 'abc'.startswith(('ab','z')) returns True; # applies to str,bytes,bytearray o.step # Read-only step value of range o; range(10).step returns 1; # applies to range o.stop # Read-only stop value of range o; range(10).stop returns 10; # applies to range o.strides # Read-only tuple containing the distance in bytes from the start # of one item to the start of the next in each of o's dimensions; # if o = memoryview(b'abcd').cast('H',[1,2]) then o.strides is # (4,2); # applies to memoryview o.strip(s) # Returns a copy of o with characters removed from both ends if # present in string s (whitespace if no s); # '0+a+b!'.strip('!+0') returns 'a+b'; # ' a b\t\n'.strip() returns 'a b'; # applies to str,bytes,bytearray o.suboffsets # TBD # applies to memoryview o.subtract(o2) # Subtracts the counts of o2's items from the counts of o's # corresponding items; if o = Counter({'a': 1}) then # o.subtract({'a': 2, 'b': -3}) returns Counter({'a': -1, 'b': 3}); # applies to Counter o.swapcase() # Returns a copy of o with all lower-/uppercase characters # converted to upper-/lowercase; # '2B|Not 2B'.swapcase() returns '2b|nOT 2b'; # applies to str,bytes,bytearray o.symmetric_difference(o2) # Same as o ^ o2 (but doesn't call o.__xor__()); # {2,3,4}.symmetric_difference({2,6} returns {3,4,6}; # applies to set,frozenset o.symmetric_difference_update(o2) # Same as o ^= o2 (but doesn't call o.__ixor__()); # if o = {2,3,4} then o.symmetric_difference_update( # {2,6}) makes o {3,4,6}; # applies to set o.title() # Returns a copy of o with the first character of each sequence of # cased characters converted to uppercase, the rest to lowercase; # '2b|noT 2b'.title() returns '2B|Not 2B'; # "they're DAD's".title() returns "They'Re Dad'S"; # applies to str,bytes,bytearray o.tobytes(order) # Returns a bytes object containing the bytes of o in the requested # order; the order may be (default is 'C' if not specified): # 'C': C-style (last index of array increments fastest); # 'F': Fortran-style (first index of array increments fastest); # 'A': the same style as used by o; # if o = memoryview(b'AbCd').cast('B',[2,2]) then o.tobytes() # returns b'AbCd' and o.tobytes('F') returns b'ACbd'; # applies to memoryview o.tolist() # Returns a list (of lists if o is multidimensional) containing the # data in o; if o = memoryview(b'abcd').cast('B',[2,2]) then # o.tolist() returns [[97, 98], [99, 100]]; # applies to memoryview o.toreadonly() # Returns a read-only copy of o; if o = memoryview(bytearray(b'A')) # and o2 = o.toreadonly() then o.readonly is False, o2.readonly is # True, o2 == o, o2 is not o, o2[0] == o[0] == 65, o[0] = 66 makes # o2[0] 66, and o2[0] = 67 raises TypeError (cannot modify # read-only memory); # applies to memoryview o.total() # Returns sum of all counts; Counter(a=2,b=3).total() returns 5; # applies to Counter o.translate(t) # Returns a copy of o with characters replaced according to table t # (o.maketrans() may be used to create t); # 'Aargh'.translate(str.maketrans('Ag','Bt','h')) returns 'Bart'; # applies to str,bytes,bytearray o.union(o2,...) # Same as o | set(o2) | ... (but doesn't call o.__or__()); # {2,3,4}.union({2,6},[3,7]) returns {2,3,4,6,7}; # applies to set,frozenset o.update(o2) # Updates o with items from o2; # for set: same as o |= set(o2) (but doesn't call o.__ior__()); # if o = {2,3,4} then o.update([2,6]) makes o {2,3,4,6}; # applies to set,dict,defaultdict,OrderedDict,Counter o.update(o2,...) # Updates o with items from o2, ...; # same as o |= set(o2) | ... (but doesn't call o.__ior__()); # if o = {2,3,4} then o.update({2,6},[3,7]) makes o {2,3,4,6,7}; # applies to set o.upper() # Returns a copy of o with all lowercase characters converted to # uppercase; '2B|Not 2B'.upper() returns '2B|NOT 2B'; # applies to str,bytes,bytearray o.values() # Returns a live view of o's values; if o = {4:5,6:7} and v = # o.values() then list(v) returns [5,7] and v will follow changes # to o; # applies to dict,defaultdict,OrderedDict,Counter o.zfill(w) # Returns a copy of o right-justified in a string of length w # filled with '0' (but a leading sign is left-justified); returns # an unmodified copy if len(o) >= w; # 'A'.zfill(4) returns '000A'; '-A'.zfill(4) returns '-00A'; # applies to str,bytes,bytearray
# Iterator and iterable type detection import collections.abc # Imports abstract base class module isinstance(o, collections.abc.Iterator) # Returns True if o is an iterator object isinstance(o, collections.abc.Iterable) # Returns True if o is an iterable object (e.g. # container or iterator), in which case iter(o) returns an iterator # for o # Iterator types si = iter('señor') # Assigns a string iterator sai = iter('hello') # Assigns a faster string iterator for a pure ascii string type(si) # Returns class with name 'str_iterator' type(sai) # Returns class with name 'str_ascii_iterator' next(si) # Returns 's', i.e. next item; raises StopIteration exception # when no more items; iterators normally can't be restarted (one # exception is a file f which can be restarted with f.seek(0)) next(si, '.') # Returns 'e'; returns '.' when no more items li = iter([3, 'hi']) # Assigns a list iterator type(li) # Returns class with name 'list_iterator' next(li) # Returns 3 ti = iter((3, 'hi')) # Assigns a tuple iterator type(ti) # Returns class with name 'tuple_iterator' next(ti) # Returns 3 seti = iter({3, 'hi'}) # Assigns a set iterator (iteration order is unpredictable) type(seti) # Returns class with name 'set_iterator' next(seti) # Returns 3 or 'hi' d = {'a':10, 'b':5} # Assigns a dictionary dki = iter(d) # Assigns a dictionary key iterator (same as iter(d.keys())) type(dki) # Returns class with name 'dict_keyiterator' next(dki) # Returns 'a' dvi = iter(d.values()) # Assigns a dictionary value iterator type(dvi) # Returns class with name 'dict_valueiterator' next(dvi) # Returns 10 dii = iter(d.items()) # Assigns a dictionary item iterator type(dii) # Returns class with name 'dict_itemiterator' next(dii) # Returns ('a', 10) bi = iter(b'hello') # Assigns a bytes iterator type(bi) # Returns class with name 'bytes_iterator' next(bi) # Returns 104 (ascii value of 'h') bai = iter(bytearray([65, 0])) # Assigns a bytearray iterator type(bai) # Returns class with name 'bytearray_iterator' next(bai) # Returns 65 ri = iter(range(5)) # Assigns a range iterator type(ri) # Returns class with name 'range_iterator' next(ri) # Returns 0 from random import random,seed # Imports functions random and seed from module random seed(0, version=2) # Sets the starting point for a well-defined pseudorandom sequence ci = iter(random, 0.1) # Assigns a callable iterator that calls function random until that # function returns 0.1 (very unlikely); note that iter() with 2 # args is quite different from iter() with 1 arg type(ci) # Returns class with name 'callable_iterator' next(ci) # Returns 0.8444218515250481 next(ci) # Returns 0.7579544029403025 se = enumerate('hello') # Assigns an enumerate object (iterator) for a string type(se) # Returns class enumerate isinstance(se, enumerate) # Returns True next(se) # Returns (0, 'h'); first item in this tuple is count next(se) # Returns (1, 'e') xe = enumerate(ri, 100) # Assigns an enumerate object for a range iterator (see above) # with count starting at 100; ri already iterated once above, so # first xe iteration triggers second ri iteration next(xe) # Returns (100, 1) next(xe) # Returns (101, 2) next(ri) # Returns 3; xe uses ri to iterate, so ri is also at item 3 z = zip('ab',[3,4]) # Assigns a zip object (iterator) type(z) # Returns class zip isinstance(z, zip) # Returns True next(z) # Returns ('a', 3) next(z) # Returns ('b', 4)Generator objects (see generator expressions and generator functions) and files are also iterators.
# 'If' statement if x == 3: x = y # Lines at same nesting level must have same indentation if not z: # (see compound statement format) y += 1 elif y != 4: pass # Does nothing (placeholder for empty statement list) else: y = x # Single-line 'if' if z: x = 1; y = 2 # Semi-colon binds tighter than colon, so doesn't end the 'if' else: y = 1; x = 2See also conditional expressions.
# Define helper function to print info def log(expr, pattern, **vars): print(f'{expr!r} matches "{pattern}"', *('and sets', ', '.join(f'{v}={vars[v]!r}' for v in vars)) * (len(vars) > 0)) # Define some variables for later use (x will be overridden by some case patterns) x = 3.14 z = 5+7j # Feed some values one by one into the match statement and see which case gets matched for expr in ((2.0,1), [2,True], True, 1, 3, 4.0, 3.0, 4, (5,'A'), 'A', ('B',3.0), (1,2,3,4), ((1,2),(3,4)), ((1,2,3),4), [3.0,(4,True)], [3.0,[4,True]], (5,6,7), (5,7,9), (None,), ()): match expr: case 2, 1.0 as y: # int and float literal patterns # will match any int/float/bool; # a pattern sequence will match any # tuple/list/... sequence; # 'as y' assigns value matching 1.0 # to y log(expr, "2, 1.0 as y", y=y) case True: # bool literal patterns only match # bool values log(expr, "True") case int(3) | float(4): # int(3) matches only integer 3, # etc; '|' means 'or' log(expr, "int(3) | float(4)") print(f' (and y is still {y!r})') # Previous assignments remain case int(x) | float(x), str(y): # int(x) matches any int and # assigns it to x log(expr, "int(x) | float(x), str(y)", x=x, y=y) case (str(x) as y) | (('B' as x, float()) as y): # float() matches any float, no # assignment log(expr, "(str(x) as y) | (('B' as x, float()) as y)", x=x, y=y) case (1 | 'C') as x, *y, _ if len(y) < 3: # *y matches zero or more values # and assigns them to y; _ matches # any single value, no assignment; # 'if' condition is checked after # pattern match and assignments log(expr, "(1 | 'C') as x, *y, _ if len(y) < 3", x=x, y=y) case (_, _), x, *_: # Tuple structure in pattern must # match ditto in value log(expr, "(_, _), x, *_", x=x) case list([float(), tuple((int(x), bool(y)))]): # list()/tuple() in pattern only # matches exactly those sequence # types log(expr, "list([float(), tuple((int(x), bool(y)))])", x=x, y=y) case z.real, x, z.imag: # Objects accessed via '.' syntax # behave like literals, they are # never assignment targets; log(expr, "z.real, x, z.imag", x=x) case _,: # This matches any single-element # tuple log(expr, "_,") case _: # This matches anything, even an # empty tuple log(expr, "_") # After the end of the match statement, any assigned variables retain their last values print(f'At end: x={x!r}, y={y!r}')
(2.0, 1) matches "2, 1.0 as y" and sets y=1 [2, True] matches "2, 1.0 as y" and sets y=True True matches "True" 1 matches "_" 3 matches "int(3) | float(4)" (and y is still True) 4.0 matches "int(3) | float(4)" (and y is still True) 3.0 matches "_" 4 matches "_" (5, 'A') matches "int(x) | float(x), str(y)" and sets x=5, y='A' 'A' matches "(str(x) as y) | (('B' as x, float()) as y)" and sets x='A', y='A' ('B', 3.0) matches "(str(x) as y) | (('B' as x, float()) as y)" and sets x='B', y=('B', 3.0) (1, 2, 3, 4) matches "(1 | 'C') as x, *y, _ if len(y) < 3" and sets x=1, y=[2, 3] ((1, 2), (3, 4)) matches "(_, _), x, *_" and sets x=(3, 4) ((1, 2, 3), 4) matches "_" [3.0, (4, True)] matches "list([float(), tuple((int(x), bool(y)))])" and sets x=4, y=True [3.0, [4, True]] matches "_" (5, 6, 7) matches "z.real, x, z.imag" and sets x=6 (5, 7, 9) matches "_" (None,) matches "_," () matches "_" At end: x=6, y=TrueA more useful example:
import enum # Imports enumeration class support import operator # Imports function versions of standard operators import itertools # Imports iterator tools, e.g. chain.from_iterable used by make_rpn import pprint # Imports pretty printing support # Define an integer enumeration class for the levels of the expression grammar, such that # an increasing level value corresponds to an increasing depth in the grammar hierarchy # (SUM + 1 == MORE_SUM, etc.) Level = enum.IntEnum('Level', 'SUM MORE_SUM TERM MORE_TERM FACTOR POWER MORE_POWER ATOM') # Define a recursive function that creates a tuple hierarchy from a list of tokens; each # tuple in the hierarchy will contain an operator function followed by its arguments (which # may in turn be tuples) def make_tree(items, level=None): # Find a case pattern below that matches the (level, items) tuple match level, items: # Handle initial call in order to do final check before returning to caller case None, all_items: match make_tree(all_items, Level.SUM): case x,: return x case _, *rest: raise ValueError(f'Unexpected token here: {rest}') # Get 1st argument (by calling 2 levels down) of a possible sequence of infix # operations; then call 1 level down to handle actual operation case Level.SUM | Level.TERM | Level.POWER, all_items: return make_tree(make_tree(all_items, Level(level + 2)), Level(level + 1)) # Handle another (possibly first) add/subtract operation if any - by calling next # level to get 2nd argument; then call same level again to check for more of such # operations case Level.MORE_SUM, (x, ('+' | '-' as op), *rest): y, *rest = make_tree(rest, Level.TERM) opfunc = operator.add if op == '+' else operator.sub return make_tree(((opfunc, x, y), *rest), Level.MORE_SUM) # Handle another (possibly first) multiply/divide operation if any - by calling # next level to get 2nd argument; then call same level again to check for more of # such operations case Level.MORE_TERM, (x, ('*' | '/' as op), *rest): y, *rest = make_tree(rest, Level.FACTOR) opfunc = operator.mul if op == '*' else operator.truediv return make_tree(((opfunc, x, y), *rest), Level.MORE_TERM) # Handle another (possibly first) prefix sign operation if any - by calling same # level again to get argument (which may include another sign operation) case Level.FACTOR, (('+' | '-' as op), *rest): x, *rest = make_tree(rest, Level.FACTOR) opfunc = operator.pos if op == '+' else operator.neg return (opfunc, x), *rest # If no more prefix sign operations, call next level to get non-signed argument case Level.FACTOR, all_items: return make_tree(all_items, Level.POWER) # Handle another (possibly first) power operation if any - by calling previous(!) # level to get 2nd argument (power operations are evaluated right to left and # arguments may include prefix operations) case Level.MORE_POWER, (x, '**', *rest): y, *rest = make_tree(rest, Level.FACTOR) return (operator.pow, x, y), *rest # Handle parentheses if any - by calling highest level to get parenthesized # content; then check for closing parenthesis case Level.ATOM, ('(', *rest): match make_tree(rest, Level.SUM): case x, ')', *rest: return x, *rest raise ValueError('Missing ")"') # At any level, if none of the above cases is valid and the first item is a simple # number or an already finalized tuple, then just pass everything up the call tree case _, (int() | float() | tuple(), *_) as x: return x # If there are no more tokens at this point, it's an error case _, (): raise ValueError('Incomplete expression') # If none of the above cases is valid, something is wrong with the next token case _, all_items: raise ValueError(f'Unexpected token here: {all_items}') # As an example of using an expression tree returned by make_tree, here's a recursive # function to calculate the numerical value of such an expression tree; it simply applies # the operator function (the first item) in each tuple to the arguments (the remaining # items in the same tuple) def calc_tree(tree): return tree[0](*map(calc_tree, tree[1:])) if isinstance(tree, tuple) else tree # As a second example, here's a recursive function that produces a reverse polish notation # representation of an expression tree; it uses chain.from_iterable to flatten the argument # trees in each tuple, and places the operator name at the end def make_rpn(tree): return (*itertools.chain.from_iterable(map(make_rpn, tree[1:])), tree[0].__name__) \ if isinstance(tree, tuple) else (tree,) # A list of tokens (e.g. produced by the get_tokens function defined in the # string tokenizer example) tokens = [ '-', 4, '**', '+', 3, '**', 2, '/', '-', '+', 8, '+', '(', 7, '-', 5, ')', '*', 6.1] # Call the 3 functions defined above and print their return values print(f'''\ Tree: {pprint.pformat(tree := make_tree(tokens), indent=2)} ----- Calculated: {calc_tree(tree)} Reference: {eval(''.join(map(str, tokens)))} ----- RPN: {make_rpn(tree)}''')
Tree: ( <built-in function add>, ( <built-in function truediv>, ( <built-in function neg>, ( <built-in function pow>, 4, (<built-in function pos>, (<built-in function pow>, 3, 2)))), (<built-in function neg>, (<built-in function pos>, 8))), (<built-in function mul>, (<built-in function sub>, 7, 5), 6.1)) ----- Calculated: 32780.2 Reference: 32780.2 ----- RPN: (4, 3, 2, 'pow', 'pos', 'pow', 'neg', 8, 'pos', 'neg', 'truediv', 7, 5, 'sub', 6.1, 'mul', 'add')
# While loop while x < 10: x += 1 if x == 5: continue # Skips rest of loop body and goes back to testing loop condition print(x) if x == y: break # Exits loop and skips 'else' part else: # Optional; does something if loop condition tested false, # i.e. when no more iterations and no break print('no break') # For loop for x in alist: # x becomes each item of alist in turn; alist is evaluated once # (Note: alist can be any iterable type or iterator) print(x) for i in range(x): # range(x) is a sequence of integers from 0 through x - 1 print(i) else: # Optional; does something when no more iterations and no break print('no break') print(x,i) # Loop variables remain visible and retain their last value after # the loop
import sys # Loop through tuple of expression strings, and set expr to each one in turn for expr in ('1/0', '[][1]', '{}[2]', '(3).a', ')', 'sys.exit(5)', '6'): print('Trying expr', expr) # Try (with all parts: 'except', 'else', 'finally') try: eval(expr) # Evaluates expression, possibly raising exception # Continue here if no exception occurred above print('- no exception') except ZeroDivisionError: # Come here on ZeroDivisionError exception in 'try' part print('- div by 0') except (IndexError, KeyError, AttributeError) as e: # Come here on any of the listed exceptions in 'try' part - with e set to exception # object print('-', repr(e)) except Exception as e: # Come here on any (not already handled) non-system-exiting exception in 'try' part # - with e set to exception object (compare with 'except:' in next example) print('- other:', repr(e)) continue # Skips rest of for-loop body (after executing 'finally' part) except SystemExit as e: # Come here on SystemExit exception in 'try' part - with e set to exception object # (SystemExit is a subclass of BaseException, not of Exception, see class diagram # under Exception Grouping) print('-', repr(e)) else: # Optional 'else' part # Come here if no exception in 'try' part; same as putting code at end of 'try' # part, but exceptions in 'else' part are not handled print('- all OK') break # Breaks out of for-loop (after executing 'finally' part) finally: # Optional 'finally' part # Always come here as last step, even on unhandled exception or # return/break/continue (in try/except/else parts) print('- finally') print('- rest of loop body')
Trying expr 1/0 - div by 0 - finally - rest of loop body Trying expr [][1] - IndexError('list index out of range') - finally - rest of loop body Trying expr {}[2] - KeyError(2) - finally - rest of loop body Trying expr (3).a - AttributeError("'int' object has no attribute 'a'") - finally - rest of loop body Trying expr ) - other: SyntaxError("unmatched ')'", ('<string>', 1, 1, ')', 1, 1)) - finally Trying expr sys.exit(5) - SystemExit(5) - finally - rest of loop body Trying expr 6 - no exception - all OK - finally
import sys # Outer 'try' which catches any unhandled exception in inner 'try' try: # Inner 'try' (with 'finally' part only) try: print('Raising exception') sys.exit() # Raises SystemExit exception which is not handled by this # 'try' (but by outer 'try') print('Unreachable') finally: # 'finally' part is also executed on unhandled exception print('Inner finally') except: # Come here on any (not already handled) exception in 'try' part; this will catch the # SystemExit exception in the inner 'try' part; note that unlike 'except Exception:' # this bare 'except:' catches all exceptions - also system-exiting ones print('Outer except')
Raising exception Inner finally Outer except
# Raise exceptions explicitly in different ways for case in range(1, 8): print('Case', case) try: try: if case == 1: raise RuntimeError # Raises exception using exception class elif case >= 2: raise RuntimeError('hi', 5) # Raises exception using exception object except Exception as e: # Catches any exception and puts it in e print('-', repr(e)) if case == 3: raise # Raises same exception e again as # though it had never been caught # by the try-except elif case == 4: raise RuntimeError('ho') # Raises new exception, but remem- # bers that this happened while # handling exception e elif case == 5: raise RuntimeError('ho') from None # Raises new exception and forgets # about exception e elif case == 6: raise RuntimeError('ho') from e # Raises new exception and notes # that it was caused by exception e elif case == 7: raise RuntimeError('ho') from KeyError('g') # Raises new exception and # notes that it was caused by # exception KeyError('g') except Exception as e: print('--', repr(e), 'with args', e.args, 'caused by', repr(e.__cause__))
Case 1 - RuntimeError() Case 2 - RuntimeError('hi', 5) Case 3 - RuntimeError('hi', 5) -- RuntimeError('hi', 5) with args ('hi', 5) caused by None Case 4 - RuntimeError('hi', 5) -- RuntimeError('ho') with args ('ho',) caused by None Case 5 - RuntimeError('hi', 5) -- RuntimeError('ho') with args ('ho',) caused by None Case 6 - RuntimeError('hi', 5) -- RuntimeError('ho') with args ('ho',) caused by RuntimeError('hi', 5) Case 7 - RuntimeError('hi', 5) -- RuntimeError('ho') with args ('ho',) caused by KeyError('g')If the outer try-except were removed from the above code, and if the loop were somehow able to restart at the next iteration every time it stopped due to an exception, then the output would be:
Case 1 - RuntimeError() Case 2 - RuntimeError('hi', 5) Case 3 - RuntimeError('hi', 5) Traceback (most recent call last): File "<string>", line 9, in <module> RuntimeError: ('hi', 5)...restarting at next loop iteration...
Case 4 - RuntimeError('hi', 5) Traceback (most recent call last): File "<string>", line 9, in <module> RuntimeError: ('hi', 5) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<string>", line 17, in <module> RuntimeError: ho...restarting at next loop iteration...
Case 5 - RuntimeError('hi', 5) Traceback (most recent call last): File "<string>", line 21, in <module> RuntimeError: ho...restarting at next loop iteration...
Case 6 - RuntimeError('hi', 5) Traceback (most recent call last): File "<string>", line 9, in <module> RuntimeError: ('hi', 5) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<string>", line 24, in <module> RuntimeError: ho...restarting at next loop iteration...
Case 7 - RuntimeError('hi', 5) KeyError: 'g' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<string>", line 27, in <module> RuntimeError: ho
Exception groups (added in Python 3.11) allow multiple exceptions to be raised at the same time, and the 'except*' syntax allows partial handling of such groups.
The UML diagram below shows how the exception grouping classes (red) relate to the normal top level exception classes (black). It also shows some examples of specific exception classes (gray). Arrows point from subclasses to the superclasses/bases they inherit from. See also about classes/types and objects
try: try: # Raise a BaseExceptionGroup containing some exceptions and a nested ExceptionGroup # (ExceptionGroup is a subclass of both BaseExceptionGroup and Exception, and # BaseExceptionGroup is a subclass of BaseException, the latter is needed for system # exiting exceptions) eg = BaseExceptionGroup('Errors', [SystemExit(1), ExceptionGroup('Sub', [ValueError(2), TypeError(3)]), ValueError(4)]) raise eg except* ValueError as e: # Come here if there are any ValueError exceptions in the (Base-)ExceptionGroup (or # in nested groups) - with e set to a copy of the group containing only those # ValueError exceptions (note the special 'except*' syntax which handles part of a # (Base-)ExceptionGroup while allowing the remaining part to propagate to other # 'except*' clauses or to outer code blocks if not handled) print('Val:', type(e).__name__, e.args) except* SystemExit as e: # Also come here if there are any SystemExit exceptions in the BaseExceptionGroup - # with e set to a copy of the BaseExceptionGroup containing only those SystemExit # exceptions print('Sys:', type(e).__name__, e.args) finally: # Always come here as last step, even if parts of the (Base-)ExceptionGroup are # unhandled print('Inner try done') # The unhandled TypeError exception above will propagate to the outer 'try' as an # ExceptionGroup containing only the TypeError exception, so the following print will # not be executed print('All parts of ExceptionGroup handled') except BaseException as e: # Catch any remaining exception (group) here (since BaseExceptionGroup is a subclass of # BaseException, it can be handled by a normal 'except' clause) print('Any:', type(e).__name__, e.args)
Val: ExceptionGroup ('Errors', [ExceptionGroup('Sub', [ValueError(2)]), ValueError(4)]) Sys: BaseExceptionGroup ('Errors', [SystemExit(1)]) Inner try done Any: ExceptionGroup ('Errors', [ExceptionGroup('Sub', [TypeError(3)])])
for excp in (AttributeError(1), SystemExit(2)): try: # Raise a simple non-group exception raise excp except* BaseException as e: # The 'except*' clause will wrap any simple non-group exception in an ExceptionGroup # (or BaseExceptionGroup if needed) and assign that to e, so e is always guaranteed # to be an ExceptionGroup (or BaseExceptionGroup) print('Any:', type(e).__name__, e.args)
Any: ExceptionGroup ('', (AttributeError(1),)) Any: BaseExceptionGroup ('', (SystemExit(2),))
assert 2 == 2 # Does nothing because the expression is True assert 2 == 3 # Raises AssertionError exception because the # expression is False
assert 2 == 3, 'Oops' # Raises AssertionError('Oops') exception due to # the False expression
# 'With' statement using context manager which suppresses exception handling on exit import contextlib # Imports with-related utilities with contextlib.suppress(ZeroDivisionError): # Enters a context where ZeroDivisionError # exceptions are suppressed print('Calculating...') # Prints something print(1/0) # Raises a ZeroDivisionError exception # which exits the block and context, but is # caught by the 'suppress' context manager, # which takes no further action print('No problem') # This line is never executed print('Done') # Execution continues here
Calculating... Done
# 4 nested 'with' contexts which open streams and redirect stdout/stderr on entry, and # close the streams and cancel the redirection on exit import contextlib, io, sys # Imports various libraries with io.StringIO() as out, \ io.StringIO() as err: # Creates a (file-like) text stream named out # and enters a context where out is guaranteed # to be closed no matter how the context is # exited; then creates err in the same way in # a nested context with (contextlib.redirect_stdout(out), contextlib.redirect_stderr(err)): # Enters 2 nested contexts where sys.stdout and # sys.stderr are redirected to out and err, # respectively; note: the 'with' expression can # be parenthesized to avoid backslash line- # continuation print('Hi') # Prints 'Hi' to out instead of to sys.stdout print('Ho', file=sys.stderr) # Prints 'Ho' to err instead of to sys.stderr print('Done') # Prints 'Done' to sys.stdout as usual print('Out:', out.getvalue(), end='') # Prints text collected in out so far print('Err:', err.getvalue(), end='') # Prints text collected in err so far out.getvalue() # Raises ValueError exception because out was # closed when outer 'with' exited
Done Out: Hi Err: Ho Traceback (most recent call last): File "<string>", line 22, in <module> ValueError: I/O operation on closed file
import io # Custom context manager class class CM: def __init__(self, init_text='', *, suppress_excp=False): # Called to construct # context manager instance print(' Creating context manager') self.init_text = init_text self.suppress_excp = suppress_excp def __enter__(self): # Called when 'with' enters context print(' Entering context') self.strm = io.StringIO(self.init_text) self.strm.seek(0, io.SEEK_END) return self.strm # Return value will be assigned to # name after 'as' in 'with' def __exit__(self, excp_type, excp_val, traceback): # Called when 'with' exits context print(' Exiting context with text:', self.strm.getvalue()) self.strm.close() if excp_type is None: # On normal exit, all args are None print(' - normal exit') # and return value is ignored else: # Else, args have exception info print(' - exception raised: %r, %r, %r' % (excp_type, excp_val, traceback.tb_lineno)) if self.suppress_excp: print(' - but suppressed') return self.suppress_excp # and returning True suppresses # further exception handling # Loop through 3 cases: normal exit, suppressed exception, unsuppressed exception for i in range(3): # i = 0, 1, 2 print('i =', i) with CM('Hi', suppress_excp=(i==1)) as s: # Creates instance of context mgr CM # (suppressing exceptions when i is 1), # calls this instance's __enter__(), # and sets s to return value from # __enter__() s.write(' ho') if i > 0: raise RuntimeError('Oops') # Raises exception (and exits 'with' # block) when i is 1 or 2 s.write(' hum') # Exits 'with' block normally # On any exit from 'with' block, context manager instance's __exit__() is called
i = 0 Creating context manager Entering context Exiting context with text: Hi ho hum - normal exit i = 1 Creating context manager Entering context Exiting context with text: Hi ho - exception raised: <class 'RuntimeError'>, RuntimeError('Oops'), 38 - but suppressed i = 2 Creating context manager Entering context Exiting context with text: Hi ho - exception raised: <class 'RuntimeError'>, RuntimeError('Oops'), 38 Traceback (most recent call last): File "<string>", line 38, in <module> RuntimeError: Oops
It is also possible (and sometimes easier than defining a complete context manager class) to use a generator function to produce a context manager object for use in a 'with' statement. The 'contextlib' standard module provides a 'contextmanager' decorator for this purpose. When applied to a generator function, the 'contextmanager' decorator automatically adds the necessary __enter__() and __exit__() special methods to the returned generator object to make it usable as a context manager.
The code before the 'yield' statement in the generator function will be executed on context entry, and the code after the 'yield' statement will be executed on context exit. Any exception raised within the 'with' block will propagate to the 'yield' statement and can be handled by a 'try' statement at that point.
import contextlib, io @contextlib.contextmanager # Adds __enter__ and __exit__ methods to # generator object returned from function # cm, so it can be used as context manager def cm(init_text='', *, suppress_excp=False): print(' Entering context') strm = io.StringIO(init_text) strm.seek(0, io.SEEK_END) excp_val = None try: yield strm # Passes control back to 'with' statement # which assigns strm to name after 'as' and # executes body of 'with' block # When 'with' block ends or raises exception, # control comes back here except Exception as e: excp_val = e if not suppress_excp: raise finally: print(' Exiting context with text:', strm.getvalue()) strm.close() if excp_val is None: print(' - normal exit') else: print(' - exception raised: %r' % excp_val) if suppress_excp: print(' - but suppressed') # Loop through 3 cases: normal exit, suppressed exception, unsuppressed exception for i in range(3): # i = 0, 1, 2 print('i =', i) with cm('Hi', suppress_excp=(i==1)) as s: # Gets context mgr instance from cm() # (suppressing exceptions when i is 1), # calls this instance's __enter__() # (which runs body of cm() until yield) # and sets s to return value from # __enter__() (i.e. yielded value) s.write(' ho') if i > 0: raise RuntimeError('Oops') # Raises exception (and exits 'with' # block) when i is 1 or 2 s.write(' hum') # Exits 'with' block normally # On any exit from 'with' block, context manager instance's __exit__() is called # (which causes execution of cm() to continue after yield if no exception, or # triggers exception handling at the point of the yield)
i = 0 Entering context Exiting context with text: Hi ho hum - normal exit i = 1 Entering context Exiting context with text: Hi ho - exception raised: RuntimeError('Oops') - but suppressed i = 2 Entering context Exiting context with text: Hi ho - exception raised: RuntimeError('Oops') Traceback (most recent call last): File "<string>", line 42, in <module> RuntimeError: Oops
import sys # Imports the sys module sys.exit() # Raises a SystemExit exception which terminates the script with # exit code 0 (usually considered to mean success) - # unless the exception is caught by a try statement sys.exit(2) # Same as above, but uses the specified exit code sys.exit('Oops!') # Same as above, but prints the specified string and uses # exit code 1 (usually considered to mean failure) sys.exit(obj) # Same as above, but converts the specified object to a string, # prints it, and uses exit code 1, unless obj is None, in which # case nothing is printed and exit code is 0 exit() # Not recommended for use in scripts; intended for use in the # interactive interpreter where it works like sys.exit() quit() # Same as exit()
import sys # Imports the sys module sys.argv # Returns a list containing the script name and command line args print(sys.argv[0]) # Prints script name (possibly full path) if len(sys.argv) > 1: # If there are any command line arguments, then ... print(sys.argv[1]) # ... print first one
# Stdout x = 10 d = {'a': 4, 'b': 5} print('d =', d) # Prints 'd = {'a': 4, 'b': 5}' + newline to stdout; # args are separated by a space print('x =', x, end=' ')# Prints 'x = 10 ' to stdout without newline (default end is '\n') print('(decimal)') # Prints '(decimal)', so whole line is 'x = 10 (decimal)' print('x', x, sep=' = ')# Prints 'x = 10' + newline to stdout (default sep is ' ') # Stderr import sys # Imports sys module print('x =', x, end='', file=sys.stderr) # Prints 'x = 10' to stderr without newline; # (default file is sys.stdout) print(' (decimal)', file=sys.stderr) # Prints ' (decimal)'; whole line: 'x = 10 (decimal)' sys.stderr.write('x = %d' % x) # Prints 'x = 10' to stderr (never automatic newline) sys.stderr.write(' (decimal)\n') # Prints ' (decimal)' + newline; # whole line printed to stderr: 'x = 10 (decimal)' a1 = ['hi\n', 'ho\n'] # List of strings incl. newlines sys.stderr.writelines(a1) # Prints 'hi' + newline + 'ho' + newline # Stdin q = input('Q: ') # Prints 'Q: ' to stdout (without newline), then reads a line from # stdin as a string, strips the newline, and assigns it to q s = sys.stdin.read() # Reads stdin until end of file and assigns the whole thing # (incl. newlines) as a string to s s = sys.stdin.readline() # Reads one line from stdin as string incl. newline; # returns empty string if no more lines a = sys.stdin.readlines() # Reads all lines from stdin as list of strings incl. newlines
Text file operations deal with str objects (i.e. Unicode text) and provide automatic platform dependent newline conversion (i.e. Python newlines '\n' are converted to/from whatever the platform uses in text files, e.g. '\r\n' for MS Windows). The default newline conversion can be controlled/disabled via the newline keyword parameter to open().
The file pointer of a file opened in text mode should only be moved (using f.seek()) to positions previously returned by f.tell(), or to the start or end of the file. No assumptions should be made about the meaning of a value returned by f.tell(), except that it can be passed to f.seek() to get back to the same position in the file. In other words, f.tell() does not necessarily return the number of bytes from the start of the file.
import io # Import io module containing file related extras # Creating/truncating + writing text file, and misc. file methods fname = 'txtfile.txt' f = open(fname, 'w') # Creates/truncates and opens file in text mode for writing # from position 0; optional newline parameter controls newline # handling: # newline=None ('\n' maps to os.linesep, this is default) # newline='' (no conversion) # newline='\n' ('\n' maps to '\n', i.e. no conversion) # newline='\r' ('\n' maps to '\r', i.e. Mac style) # newline='\r\n' ('\n' maps to '\r\n', i.e. Windows style) type(f) # Returns class io.TextIOWrapper (same for all text modes) isinstance(f, io.TextIOWrapper) # Returns True isinstance(f, io.TextIOBase) # Returns True (superclass of all text files) isinstance(f, io.IOBase) # Returns True (superclass of both text and binary files) f.tell() # Returns 0 (position of file pointer in some sense) x = 10 print('x =', x, end=' ', file=f) # Writes 'x = 10 ' to file without newline print('m', file=f) # Writes 'm' + newline; # whole line: 'x = 10 m' f.write('x = %d' % x) # Writes 'x = 10' to file (never automatic newline) and returns # 6 (number of chars written) f.write(' m\n') # Writes ' m' + newline and returns 3 (chars written); # whole line: 'x = 10 m' f.tell() # Returns 20 on Windows (position of file pointer in some sense) a1 = ['hi\n', 'ho\n'] # List of strings incl. newlines f.writelines(a1) # Writes 'hi\n' + 'ho\n' to file f.tell() # Returns 28 on Windows (position of file pointer in some sense) f.close() # Closes file # File now contains 'x = 10 m\r\nx = 10 m\r\nhi\r\nho\r\n' on # Windows # Exclusively creating text file (only if it doesn't already exist) f = open(fname, 'x') # Raises FileExistsError exception because file already exists; # same as mode 'w' if file doesn't exist # File still contains 'x = 10 m\r\nx = 10 m\r\nhi\r\nho\r\n' on # Windows # Reading text file, and misc. file methods f = open(fname, 'r') # Opens existing file in text mode for reading from pos 0 # ('r' is optional); optional newline parameter controls # newline handling: # newline=None (any newline maps to '\n' and separates lines, # this is default) # newline='' (no conversion, any newline separates lines) # newline='\n' (no conversion, only '\n' separates lines) # newline='\r' (no conversion, only '\r' separates lines) # newline='\r\n' (no conversion, only '\r\n' separates lines) f.tell() # Returns 0 (position of file pointer in some sense) s = f.read() # Reads entire file as string f.tell() # Returns 28 on Windows (position of file pointer in some sense) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) f.seek(20) # Moves file pointer to position 20 in some sense (we don't # know what 20 means, but we previously got it from f.tell() # before writing 'hi\nho\n', so we know it is that position) s = f.read() # Reads remainder of file from current position: 'hi\nho\n' f.seek(0, io.SEEK_END) # Moves file pointer to end of file and returns 28 on Windows # (position of file pointer in some sense); f.seek(-10, io.SEEK_END) # Raises io.UnsupportedOperation exception because non-zero # move from end of file is not supported for text files f.seek(0, io.SEEK_CUR) # Moves file pointer nowhere (no move) and returns 28 on Windows f.seek(-10, io.SEEK_CUR) # Raises io.UnsupportedOperation exception because non-zero # move from current position is not supported for text files f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) s = f.readline() # Reads next line from file as string incl. newline; # returns empty string if no more lines f.tell() # Returns 10 on Windows (position of file pointer in some sense) a = f.readlines() # Reads all remaining lines from file as list of strings # incl. newlines f.tell() # Returns 28 on Windows (position of file pointer in some sense) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) s = next(f) # Same as f.readline() but raises StopIteration at end of file # (files are iterators with additional control via f.seek()) for s in f: print(s, end='')# Iterates through remaining lines in file and prints each one f.close() # Closes file # File still contains 'x = 10 m\r\nx = 10 m\r\nhi\r\nho\r\n' on # Windows # 'With' statement (good practice) with open(fname) as f: # 'with' ensures that file is closed when the 'with' suite of s = f.read() # statements ends or raises an exception # File still contains 'x = 10 m\r\nx = 10 m\r\nhi\r\nho\r\n' on # Windows # Appending to text file (creating it if needed) f = open(fname, 'a') # (Creates and) opens file in text mode for appending # (writing at end) f.tell() # Returns 28 on Windows (position of file pointer in some sense # - irrelevant for mode 'a') print('hum', file=f) # Appends 'hum\n' to end of file f.tell() # Returns 33 on Windows (position of file pointer in some sense) f.close() # Closes file # File now contains 'x = 10 m\r\nx = 10 m\r\nhi\r\nho\r\nhum\r\n' # on Windows # Creating/truncating + writing & reading text file f = open(fname, 'w+') # Creates/truncates and opens file in text mode for writing # and reading f.tell() # Returns 0 (position of file pointer in some sense) s = f.read() # Reads entire file as string: '' because file was truncated print('hi', file=f) # Writes 'hi\n' to file f.tell() # Returns 4 on Windows (position of file pointer in some sense) f.close() # Closes file # File now contains 'hi\r\n' on Windows # Reading & writing text file f = open(fname, 'r+') # Opens existing file in text mode for reading and writing # (no truncating) from start of file s = f.read(1) # Reads 1 char from file as string: 'h' f.tell() # Returns 1 on Windows (position of file pointer in some sense) f.seek(0, io.SEEK_CUR) # Doesn't move file pointer but flushes line buffer (needed for # text files when switching between reading and writing) and # returns 1 on Windows (position of file pointer in some sense) print('o', end='', file=f) # Writes 'o' to file - overwriting previous 'i' in 'hi\n' f.tell() # Returns 2 on Windows (position of file pointer in some sense) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) s = f.read() # Reads entire file as string: 'ho\n' f.close() # Closes file # File now contains 'ho\r\n' on Windows # Appending to & reading text file (creating it if needed) f = open(fname, 'a+') # (Creates and) opens file in text mode for appending and # reading from end of file f.tell() # Returns 4 on Windows (position of file pointer in some sense) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) s = f.read() # Reads entire file as string: 'ho\n' f.tell() # Returns 4 on Windows (position of file pointer in some sense) f.seek(0) # Moves file pointer back to start of file (doesn't affect # append operation) print('hum', file=f) # Appends 'hum\n' to end of file; file is now 'ho\nhum\n' f.tell() # Returns 9 on Windows (position of file pointer in some sense) f.read() # Reads and returns remainder of file: '' because file pointer # was at end of file f.tell() # Returns 9 on Windows (position of file pointer in some sense) f.close() # Closes file # File now contains 'ho\r\nhum\r\n' on Windows
Binary file operations deal with bytes-like objects and do not perform any newline conversion.
The file pointer of a file opened in binary mode can be moved (using f.seek()) to any byte position within the file, and f.tell() returns the number of bytes from the start of the file to the position of the file pointer.
import io # Import io module containing file related extras # Creating/truncating + writing binary file, and misc. file methods fname = 'binfile.txt' f = open(fname, 'wb') # Creates/truncates and opens file in binary mode for writing # from position 0 type(f) # Returns class io.BufferedWriter isinstance(f, io.BufferedWriter)# Returns True isinstance(f, io.BufferedIOBase)# Returns True (superclass of all binary files) isinstance(f, io.IOBase) # Returns True (superclass of both text and binary files) f.tell() # Returns 0 (position of file pointer in bytes) x = 10 f.write(b'x = %d' % x) # Writes 'x = 10' to file (no newline) and returns 6 (number of # bytes written - always equal to size of argument) f.write(b' (decimal)\n') # Writes ' (decimal)' + newline and returns 11 (bytes written); # whole line: 'x = 10 (decimal)' a1 = [b'hi\n', b'ho\n'] # List of strings incl. newlines f.writelines(a1) # Writes 'hi\n' + 'ho\n' to file f.tell() # Returns 23 (position of file pointer in bytes) f.close() # Closes file # File now contains b'x = 10 (decimal)\nhi\nho\n' # Exclusively creating binary file (only if it doesn't already exist) f = open(fname, 'xb') # Raises FileExistsError exception because file already exists; # same as mode 'wb' if file doesn't exist # File still contains b'x = 10 (decimal)\nhi\nho\n' # Reading binary file, and misc. file methods f = open(fname, 'rb') # Opens existing file in binary mode for reading from pos 0 type(f) # Returns class io.BufferedReader isinstance(f, io.BufferedReader)# Returns True isinstance(f, io.BufferedIOBase)# Returns True (superclass of all binary files) f.tell() # Returns 0 (position of file pointer in bytes) b = f.read() # Reads entire file as bytes object f.tell() # Returns 23 (position of file pointer in bytes) f.seek(-10, io.SEEK_END) # Moves file pointer 10 bytes back from end of file and returns # 13 (new position of file pointer in bytes) f.tell() # Returns 13 (position of file pointer in bytes) f.seek(-10, io.SEEK_CUR) # Moves file pointer 10 bytes back from current position and # returns 3 (position of file pointer in bytes) f.seek(10) # Moves file pointer 10 bytes forward from start of file and # returns 10 (position of file pointer in bytes) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) b = f.readline() # Reads next line from file as bytes object incl. newline; # returns empty bytes object if no more lines f.tell() # Returns 17 (position of file pointer in bytes) a = f.readlines() # Reads all remaining lines from file as list of bytes objects # incl. newlines f.tell() # Returns 23 (position of file pointer in bytes) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) b = next(f) # Same as f.readline() but raises StopIteration at end of file # (files are iterators with additional control via f.seek()) for b in f: print(b.decode(), end='') # Iterates through remaining lines in file and # prints each one (after decoding to str) f.close() # Closes file # File still contains b'x = 10 (decimal)\nhi\nho\n' # 'With' statement (good practice) with open(fname, 'rb') as f:# 'with' ensures that file is closed when the 'with' suite of b = f.read() # statements ends or raises an exception # File still contains b'x = 10 (decimal)\nhi\nho\n' # Appending to binary file (creating it if needed) f = open(fname, 'ab') # (Creates and) opens file in binary mode for appending # (writing at end) type(f) # Returns class io.BufferedWriter isinstance(f, io.BufferedWriter)# Returns True isinstance(f, io.BufferedIOBase)# Returns True (superclass of all binary files) f.tell() # Returns 23 (position of file pointer; irrelevant for mode 'a') f.write(b'hum\n') # Appends 'hum\n' to end of file and returns 4 (bytes written) f.tell() # Returns 27 (position of file pointer in bytes) f.close() # Closes file # File now contains b'x = 10 (decimal)\nhi\nho\nhum\n' # Creating/truncating + writing & reading binary file f = open(fname, 'w+b') # Creates/truncates and opens file in binary mode for writing # and reading type(f) # Returns class io.BufferedRandom isinstance(f, io.BufferedRandom)# Returns True isinstance(f, io.BufferedIOBase)# Returns True (superclass of all binary files) b = f.read() # Reads entire file as bytes object: b'' because file was # truncated f.write(b'hi\n') # Writes 'hi\n' to file and returns 3 (bytes written) f.tell() # Returns 3 (position of file pointer in bytes) f.close() # Closes file # File now contains b'hi\n' # Reading & writing binary file f = open(fname, 'r+b') # Opens existing file in binary mode for reading and writing # (no truncating) from start of file type(f) # Returns class io.BufferedRandom isinstance(f, io.BufferedRandom)# Returns True isinstance(f, io.BufferedIOBase)# Returns True (superclass of all binary files) b = f.read(1) # Reads 1 byte from file as bytes object: b'h' f.tell() # Returns 1 (position of file pointer in bytes) f.write(b'o') # Writes 'o' to file - overwriting previous 'i' in 'hi\n' - and # returns 1 (bytes written) f.tell() # Returns 2 (position of file pointer in bytes) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) b = f.read() # Reads entire file as bytes object: b'ho\n' f.close() # Closes file # File now contains b'ho\n' # Appending to & reading binary file (creating it if needed) f = open(fname, 'a+b') # (Creates and) opens file in binary mode for appending and # reading from end of file type(f) # Returns class io.BufferedRandom isinstance(f, io.BufferedRandom)# Returns True isinstance(f, io.BufferedIOBase)# Returns True (superclass of all binary files) f.tell() # Returns 3 (position of file pointer in bytes) f.seek(0) # Moves file pointer back to start of file and returns 0 (pos) b = f.read() # Reads entire file as bytes object: b'ho\n' f.tell() # Returns 3 (position of file pointer in bytes) f.seek(0) # Moves file pointer back to start of file (doesn't affect # append operation) f.write(b'hum\n') # Appends 'hum\n' to end of file and returns 4 (bytes written); # file is now 'ho\nhum\n' f.tell() # Should return 7 but returns wrong value after append when # file pointer was not at end of file before append (bug?); # file pointer is actually at position 7, though f.read() # Reads and returns remainder of file: b'' because file pointer # was at end of file f.tell() # Returns 7 (position of file pointer in bytes) f.close() # Closes file # File now contains b'ho\nhum\n'
########################################################################################### (2 + 3) # Returns 5 (2, 3, 4) # Returns tuple (2, 3, 4) [2, 3, 4] # Returns list [2, 3, 4] {2: 3, 4: 5} # Returns dict {2: 3, 4: 5} {2, 3, 4} # Returns set {2, 3, 4} ########################################################################################### x[2] # Returns item/value with index/key 2 from tuple/list/dict/string x # (or other object with __getitem__() method) x[1:6:2] # Returns tuple/list/string by extracting slice (indices 1,3,5) # from x (x can't be a dict) x[2, 6:0:-2, # Returns item(s) from x selected by expression list of indices/ slice(6,0,-2), ...] # slices/Ellipsis; built-in types other than memoryview allow only # 1 item between [] (not Ellipsis); numpy module allows any f(2, 3, 4) # Returns result of calling function f with given arguments x.y # Returns member y of object x ########################################################################################### await asyncio.sleep(1,9)# Suspends current coroutine, runs sleep coroutine (for 1 second), # resumes this coroutine, and returns 9 (return value from sleep) ########################################################################################### 2**3 # Returns 8 (exponentiation); 4**3**2 == 4**(3**2) == 262144; # -2**-2 == -(2**(-2)) == -0.25 ########################################################################################### +1 # Returns 1 -1 # Returns -1 ~1 # Returns -2 (bitwise NOT) ########################################################################################### 2 * 3 # Returns 6 'hi' * 3 # Returns 'hihihi' (sequence repetition) x @ y # Matrix multiplication (supported by numpy module, not by built-in # types) -5 / 2 # Returns -2.5 (always a float) -5.0 // 2 # Returns -3.0 (floor div); for int: -5 // 2 == -3 -5 % 3 # Returns 1 (modulo); x == floor(x/y)*y + x%y '%0*d %X' % (5, 3, 12) # Returns '00003 C' (string formatting) ########################################################################################### 2 + 3 # Returns 5 [1,2] + [3,4] # Returns [1, 2, 3, 4] (sequence concatenation) 2 - 3 # Returns -1 {1,2,3} - {3,4} # Returns {1,2} (set difference) ########################################################################################### 6 << 2 # Returns 24 (left shift); x << y == x * 2**y; y >= 0 -6 >> 2 # Returns -2 (right shift); x >> y == x // 2**y; y >= 0 ########################################################################################### 6 & 3 # Returns 2 (bitwise AND) {1,2,3} & {3,4} # Returns {3} (set intersection) ########################################################################################### 6 ^ 3 # Returns 5 (bitwise XOR) {1,2,3} ^ {3,4} # Returns {1,2,4} (set symmetric difference) ########################################################################################### 6 | 3 # Returns 7 (bitwise OR) {1,2,3} | {3,4} # Returns {1,2,3,4} (set union) {'x':2,'y':3} | {'x':1,'z':4} # Returns {'x':1,'y':3,'z':4} (dict union) ########################################################################################### # Comparisons and tests (chainable, i.e. x < y < z means x < y and y < z (but y is # evaluated only once)): 5 in (3, 5, 8) # Returns True (membership test) 'a' not in 'hi' # Returns True (non-membership test) [] is [] # Returns False (identity test); these lists are not same object # (but immutable objects might be identical, e.g. maybe 5 is 5) {} is not {} # Returns True (non-identity test) 2 < 3 # Returns True 'ab' <= 'abc' # Returns True (lexicographic Unicode comparison) [2,3] > [2] # Returns True (lexicographic comparison of corresponding items) (3,) >= (2,5) # Returns True (lexicographic comparison of corresponding items) {2,3} > {3} # Returns True (proper superset) 2 != '2' # Returns True (different types generally compare unequal) 2 == 2.0 # Returns True (comparison works across different numeric types) ########################################################################################### not 2 # Returns False (boolean NOT) ########################################################################################### 2 and 3 # Returns 3 (boolean AND, returns 1st arg if False, else 2nd arg; # 2nd arg is not evaluated if 1st arg is returned) ########################################################################################### 0 or 'a' # Returns 'a' (boolean OR, returns 1st arg if True, else 2nd arg; # 2nd arg is not evaluated if 1st arg is returned) ########################################################################################### 2 if True else 3 # Returns 2 (conditional expression); # 3rd arg is not evaluated if 1st arg is returned, and vice versa; # (x if a else y if b else z) == (x if a else (y if b else z)) ########################################################################################### lambda x,y: x + y # Returns anonymous function which will return sum of its 2 args # (lambda expression) ########################################################################################### (x := 2) # Assignment expression; binds name x to object 2 and returns that # object; needs parentheses when at top level of expression state- # ment or at top level of right side of assignment statement (or # certain other places) ########################################################################################### #=========================================================================================# # The "operators" below this point are not officially operators, but are included here to # # show their effective relative precedence in the special contexts where they are valid # #=========================================================================================# ########################################################################################### f(x=2) # Passes named argument to function f, i.e. binds f's formal param # x to object 2 regardless of x's position in f's parameter list f(*[4, 'hi']) # Passes all items of given iterable as args to function f # (same as f(4, 'hi')) x,*y,z = range(5) # Unpacks iterable (same as x,y,z = 0,[1,2,3],4) f(**{'x': 2, 'y':3}) # Passes key/value pairs of given dictionary as named args to f # (same as f(x=2, y=3)) ########################################################################################### 2, 3 # Returns tuple (2, 3) or expression list (see enclosing operators # above and multiple assignments below for uses) ########################################################################################### (yield 2, 3) # Returns (2,3) to caller of next() or send() on generator produced # by function containing this yield, suspends generator until next # call to next()/send(), then returns None or send's argument as # return value of yield expression; needs parentheses except when # at top level of right side of assignment, or when used as a # statement, so e.g. print((yield 2)) needs double parentheses; # (yield) is same as (yield None) (yield from range(5)) # Same as executing yield in a loop taking each item from range(5) # until exhausted, then returning any StopIteration value from # range(5) (i.e. None); passes send's argument to range(5)'s send # (not supported) ########################################################################################### # Normal assignments (chainable, i.e. x = y = z means x = z, then y = z (but z is # evaluated only once); note the counterintuitive left-to-right assignment order!): x = 2 # Binds name x to object 2 o[0] = 2 # Sets item 0 of mutable object o to object 2 # (by calling o.__setitem__(0, 2)) o.x = 2 # Sets attribute x of mutable object o to object 2 # (by calling o.__setattr__('x', 2)) x = o[x] = o[x] # Chained assignments; same as tmp = o[x]; x = tmp; o[x] = tmp; # if x and o are initially 0 and [1, 2], they become 1 and [1, 1] # (o changes due to left-to-right assignment order) x, o[0], o.x = 2, 2, 2 # Multiple assignments using expression lists # Augmented assignments (not chainable; supports same targets as above except expression # lists): x += 2 # Same as x = x + 2, but x is evaluated only once and updated in # place if possible x -= 2 # x = x - 2 (but see x += 2) x *= 2 # x = x * 2 (but see x += 2) x @= y # x = x @ y (not supported by built-in types) x /= 2 # x = x / 2 (but see x += 2) x //= 2 # x = x // 2 (but see x += 2) x %= 2 # x = x % 2 (but see x += 2) x **= 2 # x = x ** 2 (but see x += 2) x >>= 2 # x = x >> 2 (but see x += 2) x <<= 2 # x = x << 2 (but see x += 2) x &= 2 # x = x & 2 (but see x += 2) x ^= 2 # x = x ^ 2 (but see x += 2) x |= 2 # x = x | 2 (but see x += 2) ###########################################################################################
'hello' + ' there\n' # Returns 'hello there\n' ('\n' is a single newline) '-' * 5 # Returns '-----' ord('A') # Returns 65 chr(65) # Returns 'A' ord('\u0E01') # Returns 3585 chr(3585) # Returns '\u0E01' (1 character) ord('\U0001F60E') # Returns 128526 chr(128526) # Returns '\U0001F60E' (1 character)
# Import Template class from string module from string import Template # Replace $-names in string with named arguments to substitute() method Template('$n $x or ${x}y $$').substitute(x='thing', n=1) # Returns '1 thing or thingy $'
# Single value (replaces %d-specifier) 'answer = %d' % 42 # Returns 'answer = 42' # Tuple of values (number of %-specifiers must match length of tuple; otherwise TypeError # exception is raised) '%s = %d' % ('answer', 42) # Returns 'answer = 42''%s = %d' % ('answer', 42, 1)# Raises TypeError exception'%s = %d' % ('answer',)# Raises TypeError exception # Single value which is a tuple (needs to be embedded in another tuple) 'mytuple = %s' % ((1, 2, 3),) # Returns 'mytuple = (1, 2, 3)' # Dictionary of values with key lookup (%()-specifiers can reference same key multiple # times, and not all keys need to be referenced; if key doesn't exist, KeyError exception # is raised) '%(x)d + %(x)d = %(z)d' % {'x':2, 'y':3, 'z':4} # Returns '2 + 2 = 4' # Minimum field width and left/right alignment (right is default, left is specified with # '-') '%3s_%-3d_%7g_%3d' % ('A', 6, -1e7, 1234) # Returns ' A_6 _ -1e+07_1234' # Dynamic minimum field width ('*' is replaced with the tuple item before the one that # replaces the whole %-specifier) '%*s_%-*d' % (2, 'A', 3, 6) # Returns ' A_6 ' # Surrounding text (no whitespace needed) 'one%dall' % 4 # Returns 'one4all' # '%%' produces a literal '%' 'level in %% = %d%%' % 50 # Returns 'level in % = 50%'
# Integer formats (all are identical, but %u is obsolete) '%d %i %u' % (-12, -13, -14) # Returns '-12 -13 -14' # Integer format with minimum field width and zero-padding (specified with '0' and field # width before 'd'; '*' is dynamic field width replaced with tuple item) '%3d_%03d_%0*d' % (-6, -7, 3, 8) # Returns ' -6_-07_008' # Integer format with forced sign (specified with '+'; '-' aligns left) '%+d_%+d_%-+3d_%+03d' % (6, -7, 8, 9) # Returns '+6_-7_+8 _+09' # Integer format with forced room for sign (specified with ' '; '-' aligns left but leaves # room for sign) '% d_% d_%- 3d_% 03d' % (6, -7, 8, 9) # Returns ' 6_-7_ 8 _ 09' # Hexadecimal formats ('#' prepends '0x' or '0X') '%x %x %X %04x %#x %#04X' % (10, -11, 12, 13, 14, 15) # Returns 'a -b C 000d 0xe 0X0F' # Octal formats ('#' prepends '0o') '%o %o %04o %#o %#05o' % (8, -9, 10, 11, 12) # Returns '10 -11 0012 0o13 0o014' # Integer format %d will round a float towards zero, but %x and %o will raise TypeError on # float '%d %d' % (4.9, -4.9) # Returns '4 -4'
# Floating point formats (%f/e/g never/always/sometimes uses exponential format) '%f %e %g' % (1e-4, 2e-4, 3e-4) # Returns '0.000100 2.000000e-04 0.0003' '%f %e %g' % (1e-5, 2e-5, 3e-5) # Returns '0.000010 2.000000e-05 3e-05' '%f %e %g' % (1e5, 2e5, 3e5) # Returns '100000.000000 2.000000e+05 300000' '%f %e %g' % (1e6, 2e6, 3e6) # Returns '1000000.000000 2.000000e+06 3e+06' # Floating point formats with uppercase 'E' (%F is same as %f) '%F %E %G' % (1e-5, 2e-5, 3e-5) # Returns '0.000010 2.000000E-05 3E-05' # Floating point formats %f/e with maximum number of digits after '.' (default 6) '%.1f %.1e' % (11.16, 22.6) # Returns '11.2 2.3e+01' # Floating point format %g with maximum total number of significant digits (default 6) '%.2g %.2g %.2g %.2g' % (11.6, 2.26, .336, 446) # Returns '12 2.3 0.34 4.5e+02' # Floating point formats with minimum field width and zero-padding (specified with '0' and # field width before '.') '%4.1f_%04.1f_%08.1e_%04.2g' % (0.06, 1.16, 2.26, 3.36) # Returns ' 0.1_01.2_02.3e+00_03.4' # Floating point formats with dynamic widths ('*' is replaced with next tuple item) '%0*.*f_%0*.*e_%0*.*g' % (4, 1, 1.16, 8, 1, 2.26, 4, 2, 3.36) # Returns'01.2_02.3e+00_03.4' # Floating point formats with forced sign (specified with '+') '%+.1f_%+.1e_%+.2g' % (1.16, 2.26, 3.36) # Returns '+1.2_+2.3e+00_+3.4' '%+.1f_%+.1e_%+.2g' % (-1.16, -2.26, -3.36) # Returns '-1.2_-2.3e+00_-3.4' # Floating point formats with forced room for sign (specified with ' ') '% .1f_% .1e_% .2g' % (1.16, 2.26, 3.36) # Returns ' 1.2_ 2.3e+00_ 3.4' '% .1f_% .1e_% .2g' % (-1.16, -2.26, -3.36) # Returns '-1.2_-2.3e+00_-3.4' # Alternate floating point formats (specified with '#' which always includes decimal point # and for %g also zeros); note that floating point formats accept int arguments but raise # TypeError on complex arguments '%#.0f %#.0e %#g' % (1, 2, 3) # Returns '1. 2.e+00 3.00000' '%.0f %.0e %g' % (1, 2, 3) # Returns '1 2e+00 3'
# String formats (%s/r/a uses str()/repr()/ascii() conversion) '%s %r %a' % (('rosé',) * 3) # Returns "rosé 'rosé' 'ros\\xe9'" # String format of any value that has a string representation 'object = %s' % ((dict(x=5), list()),) # Returns "object = ({'x': 5}, [])" # String format with maximum field width '%.3s_%.3s' % ('A', 'ABCD')", # Returns 'A_ABC' # String format with minimum and maximum field width (maximum is applied first, and may be # smaller than minimum; '-' aligns left) '%-2.3s_%2.3s_%3.2s' % ('A', 'ABCD', 'ABC')", # Returns 'A _ABC_ AB' # String format with dynamic minimum/maximum field width ('*' is replaced with next tuple # item) '%*s_%.*s_%*.*s' % (3, 'A', 2, 'ABC', 3, 2, 'ABC')", # Returns ' A_AB_ AB'
# Single-character format (with or without minimum field width) '%c_%3c' % ('A', 0xe9) # Returns 'A_ é'