Download text file or Fork me on GitHub.
if__name__=='__main__': main()<list>=<list>[from_inclusive : to_exclusive : step_size]<list>.append(<el>) <list>.extend(<collection>) <list>+= [<el>] <list>+=<collection><list>.sort() <list>.reverse() <list>=sorted(<collection>) <iter>=reversed(<list>)sum_of_elements=sum(<collection>) elementwise_sum= [sum(pair) forpairinzip(list_a, list_b)] sorted_by_second=sorted(<collection>, key=lambdael: el[1]) sorted_by_both=sorted(<collection>, key=lambdael: (el[1], el[0])) flatter_list=list(itertools.chain.from_iterable(<list>)) product_of_elems=functools.reduce(lambdaout, x: out*x, <collection>) list_of_chars=list(<str>)index=<list>.index(<el>) # Returns first index of item. <list>.insert(index, <el>) # Inserts item at index and moves the rest to the right.<el>=<list>.pop([index]) # Removes and returns item at index or from the end.<list>.remove(<el>) # Removes first occurrence of item or raises ValueError.<list>.clear() # Removes all items. <view>=<dict>.keys() <view>=<dict>.values() <view>=<dict>.items()value=<dict>.get(key, default=None) # Returns default if key does not exist.value=<dict>.setdefault(key, default=None) # Same, but also adds default to dict.<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>.update(<dict>) # Or: dict_a ={**dict_a, **dict_b}.<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.value=<dict>.pop(key) # Removes item from dictionary.{k: vfork, vin<dict>.items() ifkinkeys} # Filters dictionary by keys.>>>fromcollectionsimportCounter>>>colors= ['red', 'blue', 'yellow', 'blue', 'red', 'blue'] >>>counter=Counter(colors) Counter({'blue': 3, 'red': 2, 'yellow': 1}) >>>counter.most_common()[0] ('blue', 3)<set>=set()<set>.add(<el>) <set>.update(<collection>) <set>|={<el>} <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><set>.remove(<el>) # Throws error.<set>.discard(<el>) # Doesn't throw error.<frozenset>=frozenset(<collection>)<range>=range(to_exclusive) <range>=range(from_inclusive, to_exclusive) <range>=range(from_inclusive, to_exclusive, step_size) <range>=range(from_inclusive, to_exclusive, -step_size)from_inclusive=<range>.startto_exclusive=<range>.stopfori, elinenumerate(<collection> [, i_start]): ...- Tuple is an immutable and hashable list.
- Named tuple is its subclass with named elements.
>>>fromcollectionsimportnamedtuple>>>Point=namedtuple('Point', 'x y') >>>p=Point(1, y=2) Point(x=1, y=2) >>>p[0] 1>>>p.x1>>>getattr(p, 'y') 2>>>p._fields# Or: Point._fields ('x', 'y')- If you want to print the iterator, you need to pass it to the list() function.
- In this cheatsheet
'<collection>'can also mean an iterator.
fromitertoolsimportislice, count, repeat, cycle, chain<iter>=iter(<collection>) <iter>=iter(<function>, to_exclusive) # Sequence of return values until 'to_exclusive'.<el>=next(<iter> [, default]) # Raises StopIteration or returns 'default' on end.<iter>=count(start=0, step=1) # Returns incremented value endlessly.<iter>=repeat(<el> [, times]) # Returns element endlessly or 'times' times.<iter>=cycle(<collection>) # Repeats the sequence indefinitely.<iter>=chain(<collection>, <collection>) # Empties collections in order.<iter>=chain.from_iterable(<collection>) # Empties collections inside a collection in order.<iter>=islice(<collection>, to_exclusive) <iter>=islice(<collection>, from_inclusive, to_exclusive) <iter>=islice(<collection>, from_inclusive, to_exclusive, step_size)Convenient way to implement the iterator protocol.
defcount(start, step): whileTrue: yieldstartstart+=step>>>counter=count(10, 2) >>>next(counter), next(counter), next(counter) (10, 12, 14)<type>=type(<el>) # <class 'int'> / <class 'str'> / ...fromnumbersimportNumber, Integral, Real, Rational, Complex<bool>=isinstance(<el>, Number)<bool>=callable(<el>)<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 any whitespace character.<list>=<str>.split(sep=None, maxsplit=-1) # Splits on 'sep' str at most 'maxsplit' times.<str>=<str>.join(<list>) # Joins elements using string as separator.<str>=<str>.replace(old_str, new_str) <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>.index(<sub_str>) # Returns start index of first match.<bool>=<str>.isnumeric() # True if str contains only numeric characters.<list>=textwrap.wrap(<str>, width) # Nicely breaks string into lines.<str>=chr(<int>) # Converts int to unicode char.<int>=ord(<str>) # Converts unicode char to int.>>>ord('0'), ord('9') (48, 57) >>>ord('A'), ord('Z') (65, 90) >>>ord('a'), ord('z') (97, 122)importre<str>=re.sub(<regex>, new, text, count=0) # Substitutes all occurrences.<list>=re.findall(<regex>, text) # Returns all occurrences.<list>=re.split(<regex>, text, maxsplit=0) # Use brackets in regex to keep the matches.<Match>=re.search(<regex>, text) # Searches for first occurrence of 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.- Parameter
'flags=re.IGNORECASE'can be used with all functions. - Parameter
'flags=re.DOTALL'makes dot also accept newline. - Use
r'\1'or'\\\\1'for backreference. - Use
'?'to make operator non-greedy.
<str>=<Match>.group() # Whole match.<str>=<Match>.group(1) # Part in first bracket.<tuple>=<Match>.groups() # All bracketed parts.<int>=<Match>.start() # Start index of a match.<int>=<Match>.end() # Exclusive end index of a match.Expressions below hold true for strings that contain only ASCII characters. Use capital letter for negation.
'\d'=='[0-9]'# Digit'\s'=='[ \t\n\r\f\v]'# Whitespace'\w'=='[a-zA-Z0-9_]'# Alphanumeric<str>= f'{<el_1>},{<el_2>}'<str> = '{},{}'.format(<el_1>, <el_2>)>>>Person=collections.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>''!r' calls object's repr() method, instead of format(), to get a string.
{'abcde'!r:<10} # "'abcde' "{'abcde':.3} # 'abc'{'abcde':10.3} # 'abc '{1.23456:.3f} # '1.235'{1.23456:10.3f} # ' 1.235'{123456:10,} # ' 123,456'{123456:10_} # ' 123_456'{123456:+10} # ' +123456'{-123456:=10} # '- 123456'{123456: } # ' 123456'{-123456: } # '-123456'{65:c} # 'A'{3:08b} # '00000011' -> Binary with leading zeros.{3:0<8b} # '11000000' -> Binary with trailing zeros.'f'- Fixed point:.<precision>f'%'- Percent:.<precision>%'e'- Exponent
'c'- character'b'- binary'x'- hex'X'- HEX
<num>=pow(<num>, <num>) # Or: <num> ** <num><real>=abs(<num>) <real>=round(<real> [, ndigits])frommathimporte, pifrommathimportcos, acos, sin, asin, tan, atan, degrees, radiansfrommathimportlog, log10, log2<float>=log(<real> [, base]) # Base e, if not specified.frommathimportinf, nan, isinf, isnanfloat('inf'), float('nan')fromstatisticsimportmean, median, variance, pvariance, pstdevfromrandomimportrandom, randint, choice, shuffle<float>=random() <int>=randint(from_inclusive, to_inclusive) <el>=choice(<list>) shuffle(<list>)- Every function returns an iterator.
- If you want to print the iterator, you need to pass it to the list() function!
fromitertoolsimportproduct, combinations, combinations_with_replacement, permutations>>>product([0, 1], repeat=3) [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)] >>>product('ab', '12') [('a', '1'), ('a', '2'), ('b', '1'), ('b', '2')] >>>combinations('abc', 2) [('a', 'b'), ('a', 'c'), ('b', 'c')] >>>combinations_with_replacement('abc', 2) [('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')] >>>permutations('abc', 2) [('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]fromdatetimeimportdatetimenow=datetime.now() now.month# 3now.strftime('%Y%m%d') # '20180315'now.strftime('%Y%m%d%H%M%S') # '20180315002834'<datetime>=datetime.strptime('2015-05-12 00:39', '%Y-%m-%d %H:%M')<function>(<positional_args>) # f(0, 0)<function>(<keyword_args>) # f(x=0, y=0)<function>(<positional_args>, <keyword_args>) # f(0, y=0)deff(<nondefault_args>): # def f(x, y)deff(<default_args>): # def f(x=0, y=0)deff(<nondefault_args>, <default_args>): # def f(x, y=0)Splat expands collection into positional arguments, while splatty-splat expands 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 tuple, while splatty-splat combines zero or more keyword arguments into dictionary.
defadd(*a): returnsum(a)>>>add(1, 2, 3) 6deff(*args): # f(1, 2, 3)deff(x, *args): # f(1, 2, 3)deff(*args, z): # f(1, 2, z=3)deff(x, *args, z): # f(1, 2, z=3)deff(**kwargs): # f(x=1, y=2, z=3)deff(x, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)deff(*args, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3) | f(1, 2, 3)deff(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)deff(*args, y, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3)deff(x, *args, z, **kwargs): # f(x=1, y=2, z=3) | f(1, y=2, z=3) | f(1, 2, z=3)>>>a= (1, 2, 3) >>> [*a] [1, 2, 3]>>>head, *body, tail= [1, 2, 3, 4] >>>body [2, 3]<function>=lambda: <return_value><function>=lambda<argument_1>, <argument_2>: <return_value><list>= [i+1foriinrange(10)] # [1, 2, ..., 10]<set>={iforiinrange(10) ifi>5} #{6, 7, 8, 9}<dict>={i: i*2foriinrange(10)} #{0: 0, 1: 2, ..., 9: 18}<iter>= (i+5foriinrange(10)) # (5, 6, ..., 14)out= [i+jforiinrange(10) forjinrange(10)]out= [] foriinrange(10): forjinrange(10): out.append(i+j)fromfunctoolsimportreduce<iter>=map(lambdax: x+1, range(10)) # (1, 2, ..., 10)<iter>=filter(lambdax: x>5, range(10)) # (6, 7, 8, 9)<int>=reduce(lambdaout, x: out+x, range(10)) # 45<bool>=any(<collection>) # False if empty.<bool>=all(el[1] forelin<collection>) # True if empty.<expression_if_true>if<condition>else<expression_if_false>>>> [aifaelse'zero'forain (0, 1, 0, 3)] ['zero', 1, 'zero', 3]fromcollectionsimportnamedtuplePoint=namedtuple('Point', 'x y') point=Point(0, 0)fromenumimportEnumDirection=Enum('Direction', 'n e s w') Cutlery=Enum('Cutlery',{'fork': 1, 'knife': 2, 'spoon': 3})# Warning: Objects will share the objects that are initialized in the dictionary!Creature=type('Creature', (),{'p': Point(0, 0), 'd': Direction.n}) creature=Creature()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.
defget_multiplier(a): defout(b): returna*breturnout>>>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'.
fromfunctoolsimportpartial<function>=partial(<function> [, <arg_1>, <arg_2>, ...])>>>multiply_by_3=partial(operator.mul, 3) >>>multiply_by_3(10) 30If variable is being assigned to anywhere in the scope, it is regarded as a local variable, unless it is declared as a 'global' or 'nonlocal'.
defget_counter(): a=0defout(): nonlocalaa+=1returnareturnout>>>counter=get_counter() >>>counter(), counter(), counter() (1, 2, 3)A decorator takes a function, adds some functionality and returns it.
@decorator_namedeffunction_that_gets_passed_to_decorator(): ...Decorator that prints function's name every time it gets called.
fromfunctoolsimportwrapsdefdebug(func): @wraps(func)defout(*args, **kwargs): print(func.__name__) returnfunc(*args, **kwargs) returnout@debugdefadd(x, y): returnx+y- Wraps is a helper decorator that copies metadata of function add() to function out().
- Without it
'add.__name__'would return'out'.
Decorator that caches function's return values. All function's arguments must be hashable.
fromfunctoolsimportlru_cache@lru_cache(maxsize=None)deffib(n): returnnifn<2elsefib(n-2) +fib(n-1)fromfunctoolsimportwrapsdefdebug(print_result=False): defdecorator(func): @wraps(func)defout(*args, **kwargs): result=func(*args, **kwargs) print(func.__name__, resultifprint_resultelse'') returnresultreturnoutreturndecorator@debug(print_result=True)defadd(x, y): returnx+yclass<name>: def__init__(self, a): self.a=adef__repr__(self): class_name=self.__class__.__name__returnf'{class_name}({self.a!r})'def__str__(self): returnstr(self.a) @classmethoddefget_class_name(cls): returncls.__name__class<name>: def__init__(self, a=None): self.a=aclassPerson: def__init__(self, name, age): self.name=nameself.age=ageclassEmployee(Person): def__init__(self, name, age, staff_num): super().__init__(name, age) self.staff_num=staff_num- If eq() method is not overridden, it returns
'id(self) == id(other)', which is the same as'self is other'. - That means all objects compare not equal by default.
classMyComparable: def__init__(self, a): self.a=adef__eq__(self, other): ifisinstance(other, type(self)): returnself.a==other.areturnFalse- Hashable object needs both hash() and eq() methods and it's hash value should never change.
- Hashable objects that compare equal must have the same hash value, meaning default hash() that returns
'id(self)'will not do. - That is why Python automatically makes classes unhashable if you only implement eq().
classMyHashable: def__init__(self, a): self.__a=copy.deepcopy(a) @propertydefa(self): returnself.__adef__eq__(self, other): ifisinstance(other, type(self)): returnself.a==other.areturnFalsedef__hash__(self): returnhash(self.a)- Methods do not depend on each other, so they can be skipped if not needed.
- Any object with defined getitem() is considered iterable, even if it lacks iter().
classMySequence: def__init__(self, a): self.a=adef__len__(self): returnlen(self.a) def__getitem__(self, i): returnself.a[i] def__iter__(self): forelinself.a: yieldelclassCounter: def__init__(self): self.i=0def__call__(self): self.i+=1returnself.i>>>c=Counter() >>>c(), c(), c() (1, 2, 3)classMyOpen(): def__init__(self, filename): self.filename=filenamedef__enter__(self): self.file=open(self.filename) returnself.filedef__exit__(self, *args): self.file.close()>>>withopen('test.txt', 'w') asfile: ... file.write('Hello World!') >>>withMyOpen('test.txt') asfile: ... print(file.read()) HelloWorld!fromcopyimportcopy, deepcopy<object>=copy(<object>) <object>=deepcopy(<object>)fromenumimportEnum, autoclass<enum_name>(Enum): <member_name_1>=<value_1><member_name_2>=<value_2_a>, <value_2_b><member_name_3>=auto() @classmethoddefget_member_names(cls): return [a.nameforaincls.__members__.values()]<member>=<enum>.<member_name><member>=<enum>['<member_name>'] <member>=<enum>(<value>) name=<member>.namevalue=<member>.valuelist_of_members=list(<enum>) member_names= [a.nameforain<enum>] member_values= [a.valueforain<enum>] random_member=random.choice(list(<enum>))Cutlery=Enum('Cutlery', ['fork', 'knife', 'spoon']) Cutlery=Enum('Cutlery', 'fork knife spoon') Cutlery=Enum('Cutlery',{'fork': 1, 'knife': 2, 'spoon': 3})fromfunctoolsimportpartialLogicOp=Enum('LogicOp',{'AND': partial(lambdal, r: landr), 'OR' : partial(lambdal, r: lorr)})whileTrue: try: x=int(input('Please enter a number: ')) exceptValueError: print('Oops! That was no valid number. Try again...') else: print('Thank you.') breakraiseValueError('A very specific message!')>>>try: ... raiseKeyboardInterrupt ... finally: ... print('Goodbye, world!') Goodbye, world! Traceback (mostrecentcalllast): File"<stdin>", line2, in<module>KeyboardInterruptprint(<el_1>, ..., sep=' ', end='\n', file=sys.stdout, flush=False)- Use
'file=sys.stderr'for errors.
>>>frompprintimportpprint>>>pprint(dir()) ['__annotations__', '__builtins__', '__doc__', ...]- Reads a line from user input or pipe if present.
- Trailing newline gets stripped.
- Prompt string is printed to the standard output before reading input.
<str>=input(prompt=None)whileTrue: try: print(input()) exceptEOFError: breakimportsysscript_name=sys.argv[0] arguments=sys.argv[1:]fromargparseimportArgumentParser, FileTypep=ArgumentParser(description=<str>) p.add_argument('-<short_name>', '--<name>', action='store_true') # Flagp.add_argument('-<short_name>', '--<name>', type=<type>) # Optionp.add_argument('<name>', type=<type>, nargs=1) # Argumentp.add_argument('<name>', type=<type>, nargs='+') # Argumentsargs=p.parse_args() value=args.<name>- Use
'help=<str>'for argument description. - Use
'type=FileType(<mode>)'for files.
Opens file and returns a corresponding file object.
<file>=open('<path>', mode='r', encoding=None)'r'- Read (default).'w'- Write (truncate).'x'- Write or fail if the file already exists.'a'- Append.'w+'- Read and write (truncate).'r+'- Read and write from the start.'a+'- Read and write from the end.'t'- Text mode (default).'b'- Binary mode.
<file>.seek(0) # Move to the start of the file.<file>.seek(offset) # Move 'offset' chars/bytes from the start.<file>.seek(offset, <anchor>) # Anchor: 0 start, 1 current pos., 2 end.defread_file(filename): withopen(filename, encoding='utf-8') asfile: returnfile.readlines()defwrite_to_file(filename, text): withopen(filename, 'w', encoding='utf-8') asfile: file.write(text)fromosimportpath, listdir<bool>=path.exists('<path>') <bool>=path.isfile('<path>') <bool>=path.isdir('<path>') <list>=listdir('<path>')>>>fromglobimportglob>>>glob('../*.gif') ['1.gif', 'card.gif']frompathlibimportPathcwd=Path() <Path>=Path('<path>' [, '<path>', <Path>, ...]) <Path>=<Path>/'<dir>'/'<file>'<bool>=<Path>.exists() <bool>=<Path>.is_file() <bool>=<Path>.is_dir() <iter>=<Path>.iterdir() <iter>=<Path>.glob('<pattern>')<str>=str(<Path>) # Returns path as string.<tup.>=<Path>.parts# Returns all components as strings.<Path>=<Path>.resolve() # Returns absolute path without symlinks.<str>=<Path>.name# Final component.<str>=<Path>.stem# Final component without extension.<str>=<Path>.suffix# Final component's extension.<Path>=<Path>.parent# Path without final component.importos<str>=os.popen(<command>).read()>>>importsubprocess>>>a=subprocess.run(['ls', '-a'], stdout=subprocess.PIPE) >>>a.stdoutb'.\n..\nfile1.txt\nfile2.txt\n'>>>a.returncode0>>>importsys>>>sys.getrecursionlimit() 1000>>>sys.setrecursionlimit(5000)importcsvdefread_csv_file(filename): withopen(filename, encoding='utf-8') asfile: returncsv.reader(file, delimiter=';')defwrite_to_csv_file(filename, rows): withopen(filename, 'w', encoding='utf-8') asfile: writer=csv.writer(file, delimiter=';') writer.writerows(rows)importjson<str>=json.dumps(<object>, ensure_ascii=True, indent=None) <object>=json.loads(<str>)fromcollectionsimportOrderedDict<object>=json.loads(<str>, object_pairs_hook=OrderedDict)defread_json_file(filename): withopen(filename, encoding='utf-8') asfile: returnjson.load(file)defwrite_to_json_file(filename, an_object): withopen(filename, 'w', encoding='utf-8') asfile: json.dump(an_object, file, ensure_ascii=False, indent=2)importpickle<bytes>=pickle.dumps(<object>) <object>=pickle.loads(<bytes>)defread_pickle_file(filename): withopen(filename, 'rb') asfile: returnpickle.load(file)defwrite_to_pickle_file(filename, an_object): withopen(filename, 'wb') asfile: pickle.dump(an_object, file)importsqlite3db=sqlite3.connect('<path>') ... db.close()cursor=db.execute('<query>') ifcursor: <tuple>=cursor.fetchone() # First row.<list>=cursor.fetchall() # Remaining rows.db.execute('<query>') db.commit()Bytes object is immutable sequence of single bytes. Mutable version is called 'bytearray'.
<bytes>=b'<str>'<int>=<bytes>[<index>] <bytes>=<bytes>[<slice>] <ints>=list(<bytes>) <bytes>=b''.join(<coll_of_bytes>)<bytes>=<str>.encode(encoding='utf-8') <bytes>=<int>.to_bytes(<length>, byteorder='big|little', signed=False) <bytes>=bytes.fromhex('<hex>')<str>=<bytes>.decode(encoding='utf-8') <int>=int.from_bytes(<bytes>, byteorder='big|little', signed=False) <hex>=<bytes>.hex()defread_bytes(filename): withopen(filename, 'rb') asfile: returnfile.read()defwrite_bytes(filename, bytes_obj): withopen(filename, 'wb') asfile: file.write(bytes_obj)- Module that performs conversions between Python values and a C struct, represented as a Python bytes object.
- Machine’s native type sizes and byte order are used by default.
fromstructimportpack, unpack, iter_unpack, calcsize<bytes>=pack('<format>', <value_1> [, <value_2>, ...]) <tuple>=unpack('<format>', <bytes>) <tuples>=iter_unpack('<format>', <bytes>)>>>pack('>hhl', 1, 2, 3) b'\x00\x01\x00\x02\x00\x00\x00\x03'>>>unpack('>hhl', b'\x00\x01\x00\x02\x00\x00\x00\x03') (1, 2, 3) >>>calcsize('>hhl') 8'='- native byte order'<'- little-endian'>'- big-endian
'x'- pad byte'c'- char (1)'h'- short (2)'i'- int (4)'l'- long (4)'q'- long long (8)'f'- float (4)'d'- double (8)
List that can hold only elements of predefined type. Available types are listed above.
fromarrayimportarray<array>=array('<typecode>' [, <collection>])Used for accessing the internal data of an object that supports the buffer protocol.
<memoryview>=memoryview(<bytes>/<bytearray>/<array>) <memoryview>.release()Thread-safe list with efficient appends and pops from either side. Pronounced "deck".
fromcollectionsimportdeque<deque>=deque(<collection>, maxlen=None)<deque>.appendleft(<el>) <el>=<deque>.popleft()<deque>.extendleft(<collection>) # Collection gets reversed.<deque>.rotate(n=1) # Rotates elements to the right.fromthreadingimportThread, RLockthread=Thread(target=<function>, args=(<first_arg>, )) thread.start() ... thread.join()lock=RLock() lock.acquire() ... lock.release()>>>importhashlib>>>hashlib.md5(<str>.encode()).hexdigest() '33d0eba106da4d3ebca17fcd3f4c3d77'Inspecting code at runtime.
<list>=dir() # Names of in-scope variables.<dict>=locals() # Dict of local variables. Also vars().<dict>=globals() # Dict of global variables.<dict>=vars(<object>) <bool>=hasattr(<object>, '<attr_name>') value=getattr(<object>, '<attr_name>') setattr(<object>, '<attr_name>', value)frominspectimportsignaturesig=signature(<function>) no_of_params=len(sig.parameters) param_names=list(sig.parameters.keys())Code that generates code.
Type is the root class. If only passed the object it returns it's type (class). Otherwise it creates a new class (and not an instance!).
<class>=type(<class_name>, <parents_tuple>, <attributes_dict>)>>>Z=type('Z', (),{'a': 'abcde', 'b': 12345}) >>>z=Z()Class that creates class.
defmy_meta_class(name, parents, attrs): attrs['a'] ='abcde'returntype(name, parents, attrs)classMyMetaClass(type): def__new__(cls, name, parents, attrs): attrs['a'] ='abcde'returntype.__new__(cls, name, parents, attrs)When class is created it checks if it has metaclass defined. If not, it recursively checks if any of his parents has it defined and eventually comes to type.
classMyClass(metaclass=MyMetaClass): b=12345>>>MyClass.a, MyClass.b ('abcde', 12345)fromoperatorimportadd, sub, mul, truediv, floordiv, mod, pow, neg, abs, \ eq, ne, lt, le, gt, ge, \ not_, and_, or_, \ itemgetter, attrgetter, methodcallerimportoperatorasopproduct_of_elems=functools.reduce(op.mul, <list>) sorted_by_second=sorted(<list>, key=op.itemgetter(1)) sorted_by_both=sorted(<list>, key=op.itemgetter(1, 0)) LogicOp=enum.Enum('LogicOp',{'AND': op.and_, 'OR' : op.or_}) last_el=op.methodcaller('pop')(<list>)>>>fromastimportliteral_eval>>>literal_eval('1 + 2') 3>>>literal_eval('[1, 2, 3]') [1, 2, 3] >>>ast.literal_eval('abs(1)') ValueError: malformednodeorstringimportastfromastimportNum, BinOp, UnaryOpimportoperatorasopLEGAL_OPERATORS={ast.Add: op.add, ast.Sub: op.sub, ast.Mult: op.mul, ast.Div: op.truediv, ast.Pow: op.pow, ast.BitXor: op.xor, ast.USub: op.neg} defevaluate(expression): root=ast.parse(expression, mode='eval') returneval_node(root.body) defeval_node(node): node_type=type(node) ifnode_type==Num: returnnode.nifnode_typenotin [BinOp, UnaryOp]: raiseTypeError(node) operator_type=type(node.op) ifoperator_typenotinLEGAL_OPERATORS: raiseTypeError(f'Illegal operator {node.op}') operator=LEGAL_OPERATORS[operator_type] ifnode_type==BinOp: left, right=eval_node(node.left), eval_node(node.right) returnoperator(left, right) elifnode_type==UnaryOp: operand=eval_node(node.operand) returnoperator(operand)>>>evaluate('2 ^ 6') 4>>>evaluate('2 ** 6') 64>>>evaluate('1 + 2 * 3 ** (4 ^ 5) / (6 + -7)') -5.0- Similar to generator, but generator pulls data through the pipe with iteration, while coroutine pushes data into the pipeline with send().
- Coroutines provide more powerful data routing possibilities than iterators.
- If you built a collection of simple data processing components, you can glue them together into complex arrangements of pipes, branches, merging, etc.
- All coroutines must be "primed" by first calling next().
- Remembering to call next() is easy to forget.
- Solved by wrapping coroutines with a decorator:
defcoroutine(func): defout(*args, **kwargs): cr=func(*args, **kwargs) next(cr) returncrreturnoutdefreader(target): foriinrange(10): target.send(i) target.close() @coroutinedefadder(target): whileTrue: item= (yield) target.send(item+100) @coroutinedefprinter(): whileTrue: item= (yield) print(item) reader(adder(printer())) # 100, 101, ..., 109# $ pip3 install tqdmfromtqdmimporttqdmfromtimeimportsleepforiintqdm([1, 2, 3]): sleep(0.2) foriintqdm(range(100)): sleep(0.02)# $ pip3 install matplotlibfrommatplotlibimportpyplotpyplot.plot(<data_1> [, <data_2>, ...]) pyplot.savefig(<filename>, transparent=True) pyplot.show()# $ pip3 install tabulatefromtabulateimporttabulateimportcsvwithopen(<filename>, encoding='utf-8') asfile: lines=csv.reader(file, delimiter=';') headers= [header.title() forheaderinnext(lines)] table=tabulate(lines, headers) print(table)# $ pip3 install cursesfromcursesimportwrapperdefmain(): wrapper(draw) defdraw(screen): screen.clear() screen.addstr(0, 0, 'Press ESC to quit.') whilescreen.getch() !=27: passdefget_border(screen): fromcollectionsimportnamedtupleP=namedtuple('P', 'x y') height, width=screen.getmaxyx() returnP(width-1, height-1)# $ pip3 install requests beautifulsoup4>>>importrequests>>>frombs4importBeautifulSoup>>>url='https://en.wikipedia.org/wiki/Python_(programming_language)'>>>page=requests.get(url) >>>doc=BeautifulSoup(page.text, 'html.parser') >>>table=doc.find('table', class_='infobox vevent') >>>rows=table.find_all('tr') >>>link=rows[11].find('a')['href'] >>>ver=rows[6].find('div').text.split()[0] >>>link, ver ('https://www.python.org/', '3.7.2')# $ pip3 install bottlefrombottleimportrun, route, post, template, request, responseimportjsonrun(host='localhost', port=8080) run(host='0.0.0.0', port=80, server='cherrypy')@route('/img/<image>')defsend_image(image): returnstatic_file(image, 'images/', mimetype='image/png')@route('/<sport>')defsend_page(sport): returntemplate('<h1>{{title}}</h1>', title=sport)@post('/odds/<sport>')defodds_handler(sport): team=request.forms.get('team') home_odds, away_odds=2.44, 3.29response.headers['Content-Type'] ='application/json'response.headers['Cache-Control'] ='no-cache'returnjson.dumps([team, home_odds, away_odds])# $ pip3 install requests>>>importrequests>>>url='http://localhost:8080/odds/football'>>>data={'team': 'arsenal f.c.'} >>>response=requests.post(url, data=data) >>>response.json() ['arsenal f.c.', 2.44, 3.29]fromtimeimporttimestart_time=time() # Seconds since Epoch. ... duration=time() -start_timefromtimeimportperf_counteraspcstart_time=pc() # Seconds since restart. ... duration=pc() -start_timefromtimeitimporttimeittimeit('"-".join(str(a) for a in range(100))', number=10000, globals=globals(), setup='pass')# $ pip3 install line_profiler@profiledefmain(): a= [*range(10000)] b={*range(10000)} main()$ kernprof -lv test.py Line # Hits Time Per Hit % Time Line Contents ============================================================== 1 @profile 2 def main(): 3 1 1128.0 1128.0 27.4 a = [*range(10000)] 4 1 2994.0 2994.0 72.6 b ={*range(10000)} # $ pip3 install pycallgraphfrompycallgraphimportoutput, PyCallGraphfromdatetimeimportdatetimetime_str=datetime.now().strftime('%Y%m%d%H%M%S') filename=f'profile-{time_str}.png'drawer=output.GraphvizOutput(output_file=filename) withPyCallGraph(output=drawer): <code_to_be_profiled>Array manipulation mini language. Can run up to one hundred times faster than equivalent Python code.
# $ pip3 install numpyimportnumpyasnp<array>=np.array(<list>) <array>=np.arange(from_inclusive, to_exclusive, step_size) <array>=np.ones(<shape>) <array>=np.random.randint(from_inclusive, to_exclusive, <shape>)<array>.shape=<shape><view>=<array>.reshape(<shape>) <view>=np.broadcast_to(<array>, <shape>)<array>=<array>.sum(<axis>) indexes=<array>.argmin(<axis>)- Shape is a tuple of dimension sizes.
- Axis is an index of dimension that gets collapsed.
<el> = <2d_array>[0, 0] # First element.<1d_view> = <2d_array>[0] # First row.<1d_view> = <2d_array>[:, 0] # First column. Also [..., 0].<3d_view> = <2d_array>[None, :, :] # Expanded by dimension of size 1.<1d_array> = <2d_array>[<1d_row_indexes>, <1d_column_indexes>] <2d_array> = <2d_array>[<2d_row_indexes>, <2d_column_indexes>]<2d_bools> = <2d_array>> 0 <1d_array> = <2d_array>[<2d_bools>]- If row and column indexes differ in shape, they are combined with broadcasting.
Broadcasting is a set of rules by which NumPy functions operate on arrays of different sizes and/or dimensions.
left= [[0.1], [0.6], [0.8]] # Shape: (3, 1)right= [ 0.1 , 0.6 , 0.8 ] # Shape: (3)left= [[0.1], [0.6], [0.8]] # Shape: (3, 1)right= [[0.1 , 0.6 , 0.8]] # Shape: (1, 3) <- !2. If any dimensions differ in size, expand the ones that have size 1 by duplicating their elements:
left= [[0.1, 0.1, 0.1], [0.6, 0.6, 0.6], [0.8, 0.8, 0.8]] # Shape: (3, 3) <- !right= [[0.1, 0.6, 0.8], [0.1, 0.6, 0.8], [0.1, 0.6, 0.8]] # Shape: (3, 3) <- !>>>points=np.array([0.1, 0.6, 0.8]) [ 0.1, 0.6, 0.8] >>>wrapped_points=points.reshape(3, 1) [[ 0.1], [ 0.6], [ 0.8]] >>>distances=wrapped_points-points [[ 0. , -0.5, -0.7], [ 0.5, 0. , -0.2], [ 0.7, 0.2, 0. ]] >>>distances=np.abs(distances) [[ 0. , 0.5, 0.7], [ 0.5, 0. , 0.2], [ 0.7, 0.2, 0. ]] >>>i=np.arange(3) [0, 1, 2] >>>distances[i, i] =np.inf [[ inf, 0.5, 0.7], [ 0.5, inf, 0.2], [ 0.7, 0.2, inf]] >>>distances.argmin(1) [1, 2, 1]# $ pip3 install pillowfromPILimportImagewidth=100height=100size=width*heightpixels= [255*i/sizeforiinrange(size)] img=Image.new('HSV', (width, height)) img.putdata([(int(a), 255, 255) forainpixels]) img.convert(mode='RGB').save('test.png')fromrandomimportrandintadd_noise=lambdavalue: max(0, min(255, value+randint(-20, 20))) img=Image.open('test.png').convert(mode='HSV') img.putdata([(add_noise(h), s, v) forh, s, vinimg.getdata()]) img.convert(mode='RGB').save('test.png')'1'- 1-bit pixels, black and white, stored with one pixel per byte.'L'- 8-bit pixels, greyscale.'RGB'- 3x8-bit pixels, true color.'RGBA'- 4x8-bit pixels, true color with transparency mask.'HSV'- 3x8-bit pixels, Hue, Saturation, Value color space.
importwavefromstructimportpack, iter_unpackdefread_wav_file(filename): withwave.open(filename, 'rb') aswf: frames=wf.readframes(wf.getnframes()) return [a[0] forainiter_unpack('<h', frames)]defwrite_to_wav_file(filename, frames_int, mono=True): frames_short= (pack('<h', a) forainframes_int) withwave.open(filename, 'wb') aswf: wf.setnchannels(1ifmonoelse2) wf.setsampwidth(2) wf.setframerate(44100) wf.writeframes(b''.join(frames_short))frommathimportpi, sinframes_f= (sin(i*2*pi*440/44100) foriinrange(100000)) frames_i= (int(a*30000) forainframes_f) write_to_wav_file('test.wav', frames_i)fromrandomimportrandintadd_noise=lambdavalue: max(-32768, min(32767, value+randint(-500, 500))) frames_i= (add_noise(a) forainread_wav_file('test.wav')) write_to_wav_file('test.wav', frames_i)# pip3 install simpleaudioimportsimpleaudio, math, structfromitertoolsimportchain, repeatF=44100P1='71♪,69,,71♪,66,,62♪,66,,59♪,,,'P2='71♪,73,,74♪,73,,74,,71,,73♪,71,,73,,69,,71♪,69,,71,,67,,71♪,,,'get_pause=lambdaseconds: repeat(0, int(seconds*F)) sin_f=lambdai, hz: math.sin(i*2*math.pi*hz/F) get_wave=lambdahz, seconds: (sin_f(i, hz) foriinrange(int(seconds*F))) get_hz=lambdan: 8.176*2** (int(n) /12) parse_n=lambdanote: (get_hz(note[:2]), 0.25iflen(note) >2else0.125) get_note=lambdanote: get_wave(*parse_n(note)) ifnoteelseget_pause(0.125) frames_i=chain.from_iterable(get_note(n) forninf'{P1}{P1}{P2}'.split(',')) frames_b=b''.join(struct.pack('<h', int(a*30000)) forainframes_i) simpleaudio.play_buffer(frames_b, 1, 2, F)#!/usr/bin/env python3## Usage: .py# fromcollectionsimportnamedtuplefromenumimportEnumimportreimportsysdefmain(): pass##### UTIL#defread_file(filename): withopen(filename, encoding='utf-8') asfile: returnfile.readlines() if__name__=='__main__': main()