Download text file, Buy PDF, Fork me on GitHub or Check out FAQ.
1. Collections: List, Dictionary, Set, Tuple, Range, Enumerate, Iterator, Generator.
2. Types: Type, String, Regular_Exp, Format, Numbers, Combinatorics, Datetime.
3. Syntax: Args, Inline, Imports, Decorator, Class, Duck_Type, Enum, Exception.
4. System: Exit, Print, Input, Command_Line_Arguments, Open, Path, OS_Commands.
5. Data: JSON, Pickle, CSV, SQLite, Bytes, Struct, Array, Memory_View, Deque.
6. Advanced: Threading, Operator, Introspection, Metaprograming, Eval, Coroutines.
7. Libraries: Progress_Bar, Plot, Table, Curses, Logging, Scraping, Web, Profile,
NumPy, Image, Audio, Games, Data.
if __name__ == '__main__': # Runs main() if file wasn't imported.
main()<list> = <list>[<slice>] # Or: <list>[from_inclusive : to_exclusive : ±step]<list>.append(<el>) # Or: <list> += [<el>]
<list>.extend(<collection>) # Or: <list> += <collection><list>.sort() # Sorts in ascending order.
<list>.reverse() # Reverses the list in-place.
<list> = sorted(<collection>) # Returns a new sorted list.
<iter> = reversed(<list>) # Returns reversed iterator.sum_of_elements = sum(<collection>)
elementwise_sum = [sum(pair) for pair in zip(list_a, list_b)]
sorted_by_second = sorted(<collection>, key=lambda el: el[1])
sorted_by_both = sorted(<collection>, key=lambda el: (el[1], el[0]))
flatter_list = list(itertools.chain.from_iterable(<list>))
product_of_elems = functools.reduce(lambda out, el: out * el, <collection>)
list_of_chars = list(<str>)- For details about built-in functions sorted(), min() and max() see sortable.
- Module operator provides functions itemgetter() and mul() that offer the same functionality as lambda expressions above.
<list>.insert(<int>, <el>) # Inserts item at index and moves the rest to the right.
<el> = <list>.pop([<int>]) # Returns and removes item at index or from the end.
<int> = <list>.count(<el>) # Returns number of occurrences. Also works on strings.
<int> = <list>.index(<el>) # Returns index of the first occurrence or raises ValueError.
<list>.remove(<el>) # Removes first occurrence of the item or raises ValueError.
<list>.clear() # Removes all items. Also works on dictionary and set.<view> = <dict>.keys() # Coll. of keys that reflects changes.
<view> = <dict>.values() # Coll. of values that reflects changes.
<view> = <dict>.items() # Coll. of key-value tuples that reflects chgs.value = <dict>.get(key, default=None) # Returns default if key is missing.
value = <dict>.setdefault(key, default=None) # Returns and writes default if key is missing.
<dict> = collections.defaultdict(<type>) # Creates a dict with default value of type.
<dict> = collections.defaultdict(lambda: 1) # Creates a dict with default value 1.<dict> = dict(<collection>) # Creates a dict from coll. of key-value pairs.
<dict> = dict(zip(keys, values)) # Creates a dict from two collections.
<dict> = dict.fromkeys(keys [, value]) # Creates a dict from collection of keys.<dict>.update(<dict>) # Adds items. Replaces ones with matching keys.
value = <dict>.pop(key) # Removes item or raises KeyError.
{k for k, v in <dict>.items() if v == value} # Returns set of keys that point to the value.
{k: v for k, v in <dict>.items() if k in keys} # Returns a dictionary, filtered by keys.>>> from collections import Counter
>>> colors = ['blue', 'blue', 'blue', 'red', 'red']
>>> counter = Counter(colors)
>>> counter['yellow'] += 1
Counter({'blue': 3, 'red': 2, 'yellow': 1})
>>> counter.most_common()[0]
('blue', 3)<set> = set()<set>.add(<el>) # Or: <set> |= {<el>}
<set>.update(<collection> [, ...]) # Or: <set> |= <set><set> = <set>.union(<coll.>) # Or: <set> | <set>
<set> = <set>.intersection(<coll.>) # Or: <set> & <set>
<set> = <set>.difference(<coll.>) # Or: <set> - <set>
<set> = <set>.symmetric_difference(<coll.>) # Or: <set> ^ <set>
<bool> = <set>.issubset(<coll.>) # Or: <set> <= <set>
<bool> = <set>.issuperset(<coll.>) # Or: <set> >= <set><el> = <set>.pop() # Raises KeyError if empty.
<set>.remove(<el>) # Raises KeyError if missing.
<set>.discard(<el>) # Doesn't raise an error.- Is immutable and hashable.
- That means it can be used as a key in a dictionary or as an element in a set.
<frozenset> = frozenset(<collection>)Tuple is an immutable and hashable list.
<tuple> = ()
<tuple> = (<el>,) # Or: <el>,
<tuple> = (<el_1>, <el_2> [, ...]) # Or: <el_1>, <el_2> [, ...]Tuple's subclass with named elements.
>>> from collections import namedtuple
>>> Point = namedtuple('Point', 'x y')
>>> p = Point(1, y=2)
Point(x=1, y=2)
>>> p[0]
1
>>> p.x
1
>>> getattr(p, 'y')
2
>>> p._fields # Or: Point._fields
('x', 'y')<range> = range(to_exclusive)
<range> = range(from_inclusive, to_exclusive)
<range> = range(from_inclusive, to_exclusive, ±step_size)from_inclusive = <range>.start
to_exclusive = <range>.stopfor i, el in enumerate(<collection> [, i_start]):
...<iter> = iter(<collection>) # `iter(<iter>)` returns unmodified iterator.
<iter> = iter(<function>, to_exclusive) # A sequence of return values until 'to_exclusive'.
<el> = next(<iter> [, default]) # Raises StopIteration or returns 'default' on end.
<list> = list(<iter>) # Returns a list of iterator's remaining elements.from itertools import count, repeat, cycle, chain, islice<iter> = count(start=0, step=1) # Returns updated value endlessly. Accepts floats.
<iter> = repeat(<el> [, times]) # Returns element endlessly or 'times' times.
<iter> = cycle(<collection>) # Repeats the sequence endlessly.<iter> = chain(<coll_1>, <coll_2> [, ...]) # Empties collections in order.
<iter> = chain.from_iterable(<collection>) # Empties collections inside a collection in order.<iter> = islice(<coll>, to_exclusive) # Only returns first 'to_exclusive' elements.
<iter> = islice(<coll>, from_inclusive, …) # `to_exclusive, step_size`.- Any function that contains a yield statement returns a generator.
- Generators and iterators are interchangeable.
def count(start, step):
while True:
yield start
start += step>>> counter = count(10, 2)
>>> next(counter), next(counter), next(counter)
(10, 12, 14)- Everything is an object.
- Every object has a type.
- Type and class are synonymous.
<type> = type(<el>) # Or: <el>.__class__
<bool> = isinstance(<el>, <type>) # Or: issubclass(type(<el>), <type>)>>> type('a'), 'a'.__class__, str
(<class 'str'>, <class 'str'>, <class 'str'>)from types import FunctionType, MethodType, LambdaType, GeneratorType, ModuleTypeEach abstract base class specifies a set of virtual subclasses. These classes are then recognized by isinstance() and issubclass() as subclasses of the ABC, although they are really not. ABC can also manually decide whether or not a specific class is its virtual subclass, usually based on which methods the class has implemented. For instance, Iterable ABC looks for method iter() while Collection ABC looks for methods iter(), contains() and len().
>>> from collections.abc import Sequence, Collection, Iterable
>>> isinstance([1, 2, 3], Iterable)
True+------------------+------------+------------+------------+
| | Sequence | Collection | Iterable |
+------------------+------------+------------+------------+
| list, range, str | yes | yes | yes |
| dict, set | | yes | yes |
| iter | | | yes |
+------------------+------------+------------+------------+
>>> from numbers import Integral, Rational, Real, Complex, Number
>>> isinstance(123, Number)
True+--------------------+----------+----------+----------+----------+----------+
| | Integral | Rational | Real | Complex | Number |
+--------------------+----------+----------+----------+----------+----------+
| int | yes | yes | yes | yes | yes |
| fractions.Fraction | | yes | yes | yes | yes |
| float | | | yes | yes | yes |
| complex | | | | yes | yes |
| decimal.Decimal | | | | | yes |
+--------------------+----------+----------+----------+----------+----------+
<str> = <str>.strip() # Strips all whitespace characters from both ends.
<str> = <str>.strip('<chars>') # Strips all passed characters from both ends.<list> = <str>.split() # Splits on one or more whitespace characters.
<list> = <str>.split(sep=None, maxsplit=-1) # Splits on 'sep' str at most 'maxsplit' times.
<list> = <str>.splitlines(keepends=False) # On [\n\r\f\v\x1c-\x1e\x85\u2028\u2029] and \r\n.
<str> = <str>.join(<coll_of_strings>) # Joins elements using string as a separator.<bool> = <sub_str> in <str> # Checks if string contains a substring.
<bool> = <str>.startswith(<sub_str>) # Pass tuple of strings for multiple options.
<bool> = <str>.endswith(<sub_str>) # Pass tuple of strings for multiple options.
<int> = <str>.find(<sub_str>) # Returns start index of the first match or -1.
<int> = <str>.index(<sub_str>) # Same but raises ValueError if missing.<str> = <str>.replace(old, new [, count]) # Replaces 'old' with 'new' at most 'count' times.
<str> = <str>.translate(<table>) # Use `str.maketrans(<dict>)` to generate table.<str> = chr(<int>) # Converts int to Unicode character.
<int> = ord(<str>) # Converts Unicode character to int.- Also:
'lstrip()','rstrip()'and'rsplit()'. - Also:
'lower()','upper()','capitalize()'and'title()'.
+---------------+----------+----------+----------+----------+----------+
| | [ !#$%…] | [a-zA-Z] | [¼½¾] | [²³¹] | [0-9] |
+---------------+----------+----------+----------+----------+----------+
| isprintable() | yes | yes | yes | yes | yes |
| isalnum() | | yes | yes | yes | yes |
| isnumeric() | | | yes | yes | yes |
| isdigit() | | | | yes | yes |
| isdecimal() | | | | | yes |
+---------------+----------+----------+----------+----------+----------+
- Also:
'isspace()'checks for'[ \t\n\r\f\v\x1c-\x1f\x85…]'.
import re
<str> = re.sub(<regex>, new, text, count=0) # Substitutes all occurrences with 'new'.
<list> = re.findall(<regex>, text) # Returns all occurrences as strings.
<list> = re.split(<regex>, text, maxsplit=0) # Use brackets in regex to include the matches.
<Match> = re.search(<regex>, text) # Searches for first occurrence of the pattern.
<Match> = re.match(<regex>, text) # Searches only at the beginning of the text.
<iter> = re.finditer(<regex>, text) # Returns all occurrences as match objects.- Search() and match() return None if they can't find a match.
- Argument
'flags=re.IGNORECASE'can be used with all functions. - Argument
'flags=re.MULTILINE'makes'^'and'$'match the start/end of each line. - Argument
'flags=re.DOTALL'makes dot also accept the'\n'. - Use
r'\1'or'\\1'for backreference. - Add
'?'after an operator to make it non-greedy.
<str> = <Match>.group() # Returns the whole match. Also group(0).
<str> = <Match>.group(1) # Returns part in the first bracket.
<tuple> = <Match>.groups() # Returns all bracketed parts.
<int> = <Match>.start() # Returns start index of the match.
<int> = <Match>.end() # Returns exclusive end index of the match.- By default, decimal characters, alphanumerics and whitespaces from all alphabets are matched unless
'flags=re.ASCII'argument is used. - As shown below, it restricts special sequence matches to the first 128 characters and prevents
'\s'from accepting'[\x1c-\x1f]'(the so-called separator characters). - Use a capital letter for negation.
'\d' == '[0-9]' # Matches decimal characters.
'\w' == '[a-zA-Z0-9_]' # Matches alphanumerics and underscore.
'\s' == '[ \t\n\r\f\v]' # Matches whitespaces.<str> = f'{<el_1>}, {<el_2>}'
<str> = '{}, {}'.format(<el_1>, <el_2>)>>> from collections import namedtuple
>>> Person = namedtuple('Person', 'name height')
>>> person = Person('Jean-Luc', 187)
>>> f'{person.height}'
'187'
>>> '{p.height}'.format(p=person)
'187'{<el>:<10} # '<el> '
{<el>:^10} # ' <el> '
{<el>:>10} # ' <el>'
{<el>:.<10} # '<el>......'
{<el>:0} # '<el>'- Options can be generated dynamically:
f'{<el>:{<str/int>}[…]}'. - Adding
'!r'before the colon converts object to string by calling its repr() method.
{'abcde':10} # 'abcde '
{'abcde':10.3} # 'abc '
{'abcde':.3} # 'abc'
{'abcde'!r:10} # "'abcde' "{123456:10} # ' 123456'
{123456:10,} # ' 123,456'
{123456:10_} # ' 123_456'
{123456:+10} # ' +123456'
{123456:=+10} # '+ 123456'
{123456: } # ' 123456'
{-123456: } # '-123456'{1.23456:10.3} # ' 1.23'
{1.23456:10.3f} # ' 1.235'
{1.23456:10.3e} # ' 1.235e+00'
{1.23456:10.3%} # ' 123.456%'+--------------+----------------+----------------+----------------+----------------+
| | {<float>} | {<float>:f} | {<float>:e} | {<float>:%} |
+--------------+----------------+----------------+----------------+----------------+
| 0.000056789 | '5.6789e-05' | '0.000057' | '5.678900e-05' | '0.005679%' |
| 0.00056789 | '0.00056789' | '0.000568' | '5.678900e-04' | '0.056789%' |
| 0.0056789 | '0.0056789' | '0.005679' | '5.678900e-03' | '0.567890%' |
| 0.056789 | '0.056789' | '0.056789' | '5.678900e-02' | '5.678900%' |
| 0.56789 | '0.56789' | '0.567890' | '5.678900e-01' | '56.789000%' |
| 5.6789 | '5.6789' | '5.678900' | '5.678900e+00' | '567.890000%' |
| 56.789 | '56.789' | '56.789000' | '5.678900e+01' | '5678.900000%' |
+--------------+----------------+----------------+----------------+----------------+
+--------------+----------------+----------------+----------------+----------------+
| | {<float>:.2} | {<float>:.2f} | {<float>:.2e} | {<float>:.2%} |
+--------------+----------------+----------------+----------------+----------------+
| 0.000056789 | '5.7e-05' | '0.00' | '5.68e-05' | '0.01%' |
| 0.00056789 | '0.00057' | '0.00' | '5.68e-04' | '0.06%' |
| 0.0056789 | '0.0057' | '0.01' | '5.68e-03' | '0.57%' |
| 0.056789 | '0.057' | '0.06' | '5.68e-02' | '5.68%' |
| 0.56789 | '0.57' | '0.57' | '5.68e-01' | '56.79%' |
| 5.6789 | '5.7' | '5.68' | '5.68e+00' | '567.89%' |
| 56.789 | '5.7e+01' | '56.79' | '5.68e+01' | '5678.90%' |
+--------------+----------------+----------------+----------------+----------------+
- When both rounding up and rounding down are possible, the one that returns result with even last digit is chosen. That makes
'{6.5:.0f}'a'6'and'{7.5:.0f}'an'8'.
{90:c} # 'Z'
{90:b} # '1011010'
{90:X} # '5A'<int> = int(<float/str/bool>) # Or: math.floor(<float>)
<float> = float(<int/str/bool>) # Or: <real>e±<int>
<complex> = complex(real=0, imag=0) # Or: <real> ± <real>j
<Fraction> = fractions.Fraction(0, 1) # Or: Fraction(numerator=0, denominator=1)
<Decimal> = decimal.Decimal(<str/int>) # Or: Decimal((sign, digits, exponent))'int(<str>)'and'float(<str>)'raise ValueError on malformed strings.- Decimal numbers can be represented exactly, unlike floats where
'1.1 + 2.2 != 3.3'. - Precision of decimal operations is set with:
'decimal.getcontext().prec = <int>'.
<num> = pow(<num>, <num>) # Or: <num> ** <num>
<num> = abs(<num>) # <float> = abs(<complex>)
<num> = round(<num> [, ±ndigits]) # `round(126, -1) == 130`from math import e, pi, inf, nan, isinf, isnan
from math import sin, cos, tan, asin, acos, atan, degrees, radians
from math import log, log10, log2from statistics import mean, median, variance, stdev, pvariance, pstdevfrom random import random, randint, choice, shuffle, gauss, seed
<float> = random() # A float inside [0, 1).
<int> = randint(from_inc, to_inc) # An int inside [from_inc, to_inc].
<el> = choice(<list>) # Keeps the list intact.<int> = ±0b<bin> # Or: ±0x<hex>
<int> = int('±<bin>', 2) # Or: int('±<hex>', 16)
<int> = int('±0b<bin>', 0) # Or: int('±0x<hex>', 0)
<str> = bin(<int>) # Returns '[-]0b<bin>'.<int> = <int> & <int> # And: `0b1100 & 0b1010 == 0b1000`.
<int> = <int> | <int> # Or: `0b1100 | 0b1010 == 0b1110`.
<int> = <int> ^ <int> # Xor: `0b1100 ^ 0b1010 == 0b0110`.
<int> = <int> << n_bits # Left shift (>> for right)
<int> = ~<int> # Not (also: -<int> - 1)- Every function returns an iterator.
- If you want to print the iterator, you need to pass it to the list() function first!
from itertools import product, combinations, combinations_with_replacement, permutations>>> product([0, 1], repeat=3)
[(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), ..., (1, 1, 1)]>>> product('abc', 'abc') # a b c
[('a', 'a'), ('a', 'b'), ('a', 'c'), # a x x x
('b', 'a'), ('b', 'b'), ('b', 'c'), # b x x x
('c', 'a'), ('c', 'b'), ('c', 'c')] # c x x x>>> combinations('abc', 2) # a b c
[('a', 'b'), ('a', 'c'), # a . x x
('b', 'c')] # b . . x>>> combinations_with_replacement('abc', 2) # a b c
[('a', 'a'), ('a', 'b'), ('a', 'c'), # a x x x
('b', 'b'), ('b', 'c'), # b . x x
('c', 'c')] # c . . x>>> permutations('abc', 2) # a b c
[('a', 'b'), ('a', 'c'), # a . x x
('b', 'a'), ('b', 'c'), # b x . x
('c', 'a'), ('c', 'b')] # c x x .- Module 'datetime' provides 'date'
<D>, 'time'<T>, 'datetime'<DT>and 'timedelta'<TD>classes. All are immutable and hashable. - Time and datetime objects can be 'aware'
<a>, meaning they have defined timezone, or 'naive'<n>, meaning they don't. - If object is naive, it is presumed to be in the system's timezone.
from datetime import date, time, datetime, timedelta
from dateutil.tz import UTC, tzlocal, gettz, datetime_exists, resolve_imaginary<D> = date(year, month, day)
<T> = time(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, fold=0)
<DT> = datetime(year, month, day, hour=0, minute=0, second=0, ...)
<TD> = timedelta(days=0, seconds=0, microseconds=0, milliseconds=0,
minutes=0, hours=0, weeks=0)- Use
'<D/DT>.weekday()'to get the day of the week (Mon == 0). 'fold=1'means the second pass in case of time jumping back for one hour.'<DTa> = resolve_imaginary(<DTa>)'fixes DTs that fall into the missing hour.
<D/DTn> = D/DT.today() # Current local date or naive datetime.
<DTn> = DT.utcnow() # Naive datetime from current UTC time.
<DTa> = DT.now(<tzinfo>) # Aware datetime from current tz time.- To extract time use
'<DTn>.time()','<DTa>.time()'or'<DTa>.timetz()'.
<tzinfo> = UTC # UTC timezone. London without DST.
<tzinfo> = tzlocal() # Local timezone. Also gettz().
<tzinfo> = gettz('<Continent>/<City>') # 'Continent/City_Name' timezone or None.
<DTa>
47D4
= <DT>.astimezone(<tzinfo>) # Datetime, converted to the passed timezone.
<Ta/DTa> = <T/DT>.replace(tzinfo=<tzinfo>) # Unconverted object with a new timezone.<D/T/DT> = D/T/DT.fromisoformat('<iso>') # Object from ISO string. Raises ValueError.
<DT> = DT.strptime(<str>, '<format>') # Datetime from str, according to format.
<D/DTn> = D/DT.fromordinal(<int>) # D/DTn from days since the Gregorian NYE 1.
<DTn> = DT.fromtimestamp(<real>) # Local time DTn from seconds since the Epoch.
<DTa> = DT.fromtimestamp(<real>, <tz.>) # Aware datetime from seconds since the Epoch.- ISO strings come in following forms:
'YYYY-MM-DD','HH:MM:SS.ffffff[±<offset>]', or both separated by an arbitrary character. Offset is formatted as:'HH:MM'. - Epoch on Unix systems is:
'1970-01-01 00:00 UTC','1970-01-01 01:00 CET', ...
<str> = <D/T/DT>.isoformat(sep='T') # Also timespec='auto/hours/minutes/seconds'.
<str> = <D/T/DT>.strftime('<format>') # Custom string representation.
<int> = <D/DT>.toordinal() # Days since Gregorian NYE 1, ignoring time and tz.
<float> = <DTn>.timestamp() # Seconds since the Epoch, from DTn in local tz.
<float> = <DTa>.timestamp() # Seconds since the Epoch, from DTa.>>> dt = datetime.strptime('2015-05-14 23:39:00.00 +0200', '%Y-%m-%d %H:%M:%S.%f %z')
>>> dt.strftime("%A, %dth of %B '%y, %I:%M%p %Z")
"Thursday, 14th of May '15, 11:39PM UTC+02:00"'%Z'only accepts'UTC/GMT'and local timezone's code.'%z'also accepts'±HH:MM'.- For abbreviated weekday and month use
'%a'and'%b'.
<D/DT> = <D/DT> ± <TD> # Returned datetime can fall into missing hour.
<TD> = <D/DTn> - <D/DTn> # Returns the difference, ignoring time jumps.
<TD> = <DTa> - <DTa> # Ignores time jumps if they share tzinfo object.
<TD> = <TD> * <real> # Also: <TD> = abs(<TD>) and <TD> = <TD> ±% <TD>
<float> = <TD> / <TD> # How many weeks/years there are in TD. Also '//'.<function>(<positional_args>) # f(0, 0)
<function>(<keyword_args>) # f(x=0, y=0)
<function>(<positional_args>, <keyword_args>) # f(0, y=0)def f(<nondefault_args>): # def f(x, y):
def f(<default_args>): # def f(x=0, y=0):
def f(<nondefault_args>, <default_args>): # def f(x, y=0):Splat expands a collection into positional arguments, while splatty-splat expands a dictionary into keyword arguments.
args = (1, 2)
kwargs = {'x': 3, 'y': 4, 'z': 5}
func(*args, **kwargs)func(1, 2, x=3, y=4, z=5)Splat combines zero or more positional arguments into a tuple, while splatty-splat combines zero or more keyword arguments into a dictionary.
def add(*a):
return sum(a)>>> add(1, 2, 3)
6def f(x, y, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
def f(*, x, y, z): # f(x=1, y=2, z=3)
def f(x, *, y, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3)
def f(x, y, *, z): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)def f(*args): # f(1, 2, 3)
def f(x, *args): # f(1, 2, 3)
def f(*args, z): # f(1, 2, z=3)
def f(x, *args, z): # f(1, 2, z=3)def f(**kwargs): # f(x=1, y=2, z=3)
def f(x, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)
def f(*, x, **kwargs): # f(x=1, y=2, z=3)def f(*args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
def f(x, *args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)
def f(*args, y, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)
def f(x, *args, z, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)<list> = [*<collection> [, ...]]
<set> = {*<collection> [, ...]}
<tuple> = (*<collection>, [...])
<dict> = {**<dict> [, ...]}head, *body, tail = <collection><func> = lambda: <return_value>
<func> = lambda <arg_1>, <arg_2>: <return_value><list> = [i+1 for i in range(10)] # [1, 2, ..., 10]
<set> = {i for i in range(10) if i > 5} # {6, 7, 8, 9}
<iter> = (i+5 for i in range(10)) # (5, 6, ..., 14)
<dict> = {i: i*2 for i in range(10)} # {0: 0, 1: 2, ..., 9: 18}>>> [l+r for l in 'abc' for r in 'abc']
['aa', 'ab', 'ac', ..., 'cc']<iter> = map(lambda x: x + 1, range(10)) # (1, 2, ..., 10)
<iter> = filter(lambda x: x > 5, range(10)) # (6, 7, 8, 9)
<obj> = reduce(lambda out, x: out + x, range(10)) # 45- Reduce must be imported from the functools module.
<bool> = any(<collection>) # Is `bool(el)` True for any element.
<bool> = all(<collection>) # Is True for all elements or empty.<obj> = <exp_if_true> if <condition> else <exp_if_false>>>> [a if a else 'zero' for a in (0, 1, 2, 3)]
['zero', 1, 2, 3]from collections import namedtuple
Point = namedtuple('Point', 'x y')
point = Point(0, 0)from enum import Enum
Direction = Enum('Direction', 'n e s w')
direction = Direction.nfrom dataclasses import make_dataclass
Creature = make_dataclass('Creature', ['loc', 'dir'])
creature = Creature(point, direction)import <module> # Imports a built-in or '<module>.py'.
import <package> # Imports a built-in or '<package>/__init__.py'.
import <package>.<module> # Imports a built-in or '<package>/<module>.py'.- Package is a collection of modules, but it can also define its own objects.
- On a filesystem this corresponds to a directory of Python files with an optional init script.
- Running
'import <package>'does not automatically provide access to the package's modules unless they are explicitly imported in its init script.
We have a closure in Python when:
- A nested function references a value of its enclosing function and then
- the enclosing function returns the nested function.
def get_multiplier(a):
def out(b):
return a * b
return out>>> multiply_by_3 = get_multiplier(3)
>>> multiply_by_3(10)
30- If multiple nested functions within enclosing function reference the same value, that value gets shared.
- To dynamically access function's first free variable use
'<function>.__closure__[0].cell_contents'.
from functools import partial
<function> = partial(<function> [, <arg_1>, <arg_2>, ...])>>> import operator as op
>>> multiply_by_3 = partial(op.mul, 3)
>>> multiply_by_3(10)
30- Partial is also useful in cases when function needs to be passed as an argument, because it enables us to set its arguments beforehand.
- A few examples being:
'defaultdict(<function>)','iter(<function>, to_exclusive)'and dataclass's'field(default_factory=<function>)'.
If variable is being assigned to anywhere in the scope, it is regarded as a local variable, unless it is declared as a 'global' or a 'nonlocal'.
def get_counter():
i = 0
def out():
nonlocal i
i += 1
return i
return out>>> counter = get_counter()
>>> counter(), counter(), counter()
(1, 2, 3)- A decorator takes a function, adds some functionality and returns it.
- It can be any callable, but is usually implemented as a function that returns a closure.
@decorator_name
def function_that_gets_passed_to_decorator():
...Decorator that prints function's name every time it gets called.
from functools import wraps
def debug(func):
@wraps(func)
def out(*args, **kwargs):
print(func.__name__)
return func(*args, **kwargs)
return out
@debug
def add(x, y):
return x + y- Wraps is a helper decorator that copies the metadata of the passed function (func) to the function it is wrapping (out).
- Without it
'add.__name__'would return'out'.
Decorator that caches function's return values. All function's arguments must be hashable.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
return n if n < 2 else fib(n-2) + fib(n-1)- CPython interpreter limits recursion depth to 1000 by default. To increase it use
'sys.setrecursionlimit(<depth>)'.
A decorator that accepts arguments and returns a normal decorator that accepts a function.
from functools import wraps
def debug(print_result=False):
def decorator(func):
@wraps(func)
def out(*args, **kwargs):
result = func(*args, **kwargs)
print(func.__name__, result if print_result else '')
return result
return out
return decorator
@debug(print_result=True)
def add(x, y):
return x + yclass <name>:
def __init__(self, a):
self.a = a
def __repr__(self):
class_name = self.__class__.__name__
return f'{class_name}({self.a!r})'
def __str__(self):
return str(self.a)
@classmethod
def get_class_name(cls):
return cls.__name__- Return value of repr() should be unambiguous and of str() readable.
- If only repr() is defined, it will also be used for str().
print(<el>)
print(f'{<el>}')
raise Exception(<el>)
loguru.logger.debug(<el>)
csv.writer(<file>).writerow([<el>])print([<el>])
print(f'{<el>!r}')
>>> <el>
loguru.logger.exception()
Z = dataclasses.make_dataclass('Z', ['a']); print(Z(<el>))class <name>:
def __init__(self, a=None):
self.a = aclass Person:
def __init__(self, name, age):
self.name = name
self.age = age
class Employee(Person):
def __init__(self, name, age, staff_num):
super().__init__(name, age)
self.staff_num = staff_numclass A: pass
class B: pass
class C(A, B): passMRO determines the order in which parent classes are traversed when searching for a method:
>>> C.mro()
[<class 'C'>, <class 'A'>, <class 'B'>, <class 'object'>]

