├── .travis.yml ├── CONTRIBUTORS ├── LICENSE.txt ├── PyTrickBase.txt ├── README.md ├── argumentunpacking.py ├── boolasint.py ├── boolfast.py ├── boolisslow.py ├── boolisslow.py2 ├── cacheproperty.py ├── calculator.py ├── chainedcomparison.py ├── codetofunction.py ├── common_seq_method.py ├── concatenatestrings.py ├── conditionalassignment.py ├── conditionalfunctioncall.py ├── contextmanagers.py ├── controlwhitespaces.py ├── copylist.py ├── deck_as_list.py ├── dictdefaultvalue.py ├── dictionaryget.py ├── dictsortbyvalue.py ├── dictswapkeysvalues.py ├── exec.py ├── extendediterableunpacking.py3 ├── flattenlist.py ├── flattenlist.py2 ├── flattenlist.py3 ├── forelse.py ├── ifelsecommentswitch.py ├── keydefaultdict.py ├── listtocommaseparated.py ├── loopoverlappingdicts.py ├── loopoverlappingdicts.py3 ├── maxsplit.py ├── merge_dict.py ├── merge_dict.py3 ├── metatable.py ├── minmaxindex.py ├── namedformatting.py ├── namedformatting.py3 ├── nested_functions.py ├── objgetnamedattribute.py ├── rawinputintegers.py ├── removeduplicatefromlist.py ├── reverselist.py ├── reversestring.py ├── setglobalvariables.py ├── setoperators.py ├── socketmsghandling.py ├── sortlistkeepindices.py ├── stepslice.py ├── switch_case_statments_with_dict.py ├── transpose.py ├── tree.py ├── tryelse.py ├── unique_by_attr.py ├── valueswapping.py └── whileelse.py /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | before_install: 5 | - sudo apt-get update 6 | - sudo apt-get install -y python python3 7 | script: 8 | - | 9 | set -e 10 | 11 | for file in $(ls *.py); do 12 | echo "Executing with Python 2: $file" 13 | python2 $file 14 | echo "Executing with Python 3: $file" 15 | python3 $file 16 | done 17 | 18 | for file in $(ls *.py2); do 19 | echo "Executing with Python 2: $file" 20 | python2 $file 21 | done 22 | 23 | for file in $(ls *.py3); do 24 | echo "Executing with Python 3: $file" 25 | python3 $file 26 | done 27 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | - brennerm 2 | - agumonkey 3 | - obeleh 4 | - Prooffreader 5 | - cgopalan (cgopalan.github.io) 6 | - anabalica (ana-balica.github.io) 7 | - dharmit (github.com/dharmit) 8 | - shyboynccu (github.com/shyboynccu) 9 | - illuz 10 | - tutoringsteve 11 | - Kzinglzy 12 | - waveform80 (github.com/waveform80) 13 | - thatneat (github.com/thatneat) 14 | - bruno314 (github.com/bruno314) 15 | - rickhau 16 | - oztalha (github.com/oztalha) 17 | - nikhiln (github.com/nikhiln) 18 | - raulcd (github.com/raulcd) 19 | - betezed (github.com/betezed) 20 | - transcranial (github.com/transcranial) 21 | - st0le (http://st0le.github.io) 22 | - goutham2027 (github.com/goutham2027) 23 | - dcbaker 24 | - isayme 25 | - Skycker (github.com/Skycker) 26 | - vvscloud (github.com/vvscloud) 27 | - xamvolagis (github.com/xamvolagis) 28 | - richardasaurus (richard@richard.do) 29 | - lipinski (github.com/lipinski) 30 | - falceeffect (github.com/falceeffect) 31 | - felipevolpone (github.com/felipevolpone) 32 | - awsh (github.com/awsh) 33 | - shiyanhui (github.com/shiyanhui) 34 | - pussbb (github.com/pussbb) 35 | - flint (github.com/flintforge) 36 | - kazuhiko (github.com/JohnTitor00) 37 | - sfdye (github.com/sfdye) 38 | - ofek (https://github.com/ofek) 39 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Max Brenner 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PyTrickBase.txt: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """""" 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/brennerm/PyTricks.svg?branch=master)](https://travis-ci.org/brennerm/PyTricks) 2 | 3 | ## Intention 4 | Creating a knowledge base of unpopular Python built-in features to save a lot of unnecessary code. 5 | 6 | ## Contribute 7 | Feel free to use the PyTrickBase.txt as a starting point. 8 | 9 | 1. Pull request: 10 | 11 | Send a pull request with your PyTrick, containing example code and a documentation one-liner. Be sure to add yourself to the contributors. 12 | 13 | 2. Issue comment: 14 | 15 | Add your Python snippet and your documentation as a comment on Issue#1. I will take care of adding your PyTrick and you as a contributor. 16 | 17 | ### Requirements 18 | - only use the standard Python library 19 | - compared to the "general approach": 20 | - improve readability 21 | - improve performance 22 | - implement functionality in a shorter way 23 | 24 | ## Contact 25 | 1. message me at [@__brennerm](https://twitter.com/__brennerm) 26 | 2. send an email to xam.rennerb@gmail.com 27 | -------------------------------------------------------------------------------- /argumentunpacking.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """simple tuple and dictionary unpacking""" 3 | def product(a, b): 4 | return a * b 5 | 6 | def fn_iterable(): 7 | return [2, 3] 8 | 9 | def fn_dict(): 10 | return {'a': 2, 'b': 3} 11 | 12 | argument_tuple = (2, 3) 13 | argument_dict = {'a': 2, 'b': 3} 14 | 15 | print(product(*argument_tuple)) 16 | print(product(**argument_dict)) 17 | 18 | # unpacking works as well on function return values 19 | print(product(*fn_iterable())) 20 | print(product(**fn_dict())) 21 | -------------------------------------------------------------------------------- /boolasint.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """True and False can be used as integer values 3 | True -> 1 4 | False -> 0 5 | """ 6 | a = 5 7 | print(isinstance(a, int) + (a <= 10)) 8 | print(["is odd", "is even"][a % 2 == 0]) -------------------------------------------------------------------------------- /boolfast.py: -------------------------------------------------------------------------------- 1 | """Getting the truthyness via bool(obj) is slow because it is a global and 2 | therefore involves multiple namespace lookups. You can use the keyword `not` 3 | to avoid the overheard i.e. `not not obj`. 4 | """ 5 | 6 | import timeit 7 | 8 | slow_setup = """ 9 | class C: 10 | def __init__(self): 11 | self.some_val = 5 12 | def __bool__(self): 13 | return bool(self.some_val) 14 | a = C() 15 | """ 16 | 17 | fast_setup = """ 18 | class C: 19 | def __init__(self): 20 | self.some_val = 5 21 | def __bool__(self): 22 | return not not self.some_val 23 | a = C() 24 | """ 25 | 26 | # on my machine: 27 | 28 | # 0.433618037256565 29 | print(timeit.timeit('a.__bool__()', slow_setup)) 30 | 31 | # 0.2220980115553175 32 | print(timeit.timeit('a.__bool__()', fast_setup)) 33 | 34 | # 0.40519480762077364 35 | print(timeit.timeit('if a:pass', slow_setup)) 36 | 37 | # 0.24311949953334988 38 | print(timeit.timeit('if a:pass', fast_setup)) 39 | -------------------------------------------------------------------------------- /boolisslow.py: -------------------------------------------------------------------------------- 1 | """ 2 | True and False are keywords in python3, but not in Python2. In Python2 3 | the value of True is 1, and the value of False is 0. True and False can be 4 | regarded as vars and thus they are slow in while loop. 5 | 6 | By the way, True and False can be changed in Python2. 7 | 8 | Note: This leads to a performance improvement only in Python2. 9 | """ 10 | import sys 11 | from timeit import timeit 12 | 13 | 14 | def test_true(): 15 | count = 100 16 | while True: # here is True 17 | if count < 0: 18 | break 19 | count -= 1 20 | 21 | 22 | def test_1(): 23 | count = 100 24 | while 1: # here is 1 25 | if count < 0: 26 | break 27 | count -= 1 28 | 29 | 30 | # test_true is about 5.01579904556 seconds 31 | # test_1 is about 3.70646500587 seconds 32 | print(timeit(test_true, number=1000000)) 33 | print(timeit(test_1, number=1000000)) 34 | -------------------------------------------------------------------------------- /boolisslow.py2: -------------------------------------------------------------------------------- 1 | # True and False can be changed in python2 2 | True = 0 3 | False = 100 4 | 5 | print(True) 6 | print(False) 7 | -------------------------------------------------------------------------------- /cacheproperty.py: -------------------------------------------------------------------------------- 1 | class PropertyCache(object): 2 | """ a decorator to cache property 3 | """ 4 | 5 | def __init__(self, func): 6 | self.func = func 7 | 8 | def __get__(self, obj, cls): 9 | if not obj: 10 | return self 11 | value = self.func(obj) 12 | setattr(obj, self.func.__name__, value) 13 | return value 14 | 15 | 16 | class Foo: 17 | def __init__(self): 18 | self._property_to_be_cached = 'result' 19 | 20 | @PropertyCache 21 | def property_to_be_cached(self): 22 | print('compute') 23 | return self._property_to_be_cached 24 | 25 | test = Foo() 26 | 27 | print(test.property_to_be_cached) 28 | print(test.property_to_be_cached) 29 | 30 | -------------------------------------------------------------------------------- /calculator.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | This program lets you create a simple command line calculator without using 4 | the 'if..else' construct. It uses built-in 'operator' module to accomplish the 5 | same 6 | 7 | Created with help of an answer on stackoverflow. Don't have the exact link. 8 | """ 9 | 10 | import operator 11 | ops = { 12 | "+": operator.add, 13 | "-": operator.sub, 14 | "/": operator.truediv, 15 | "*": operator.mul, 16 | "**": pow 17 | } 18 | 19 | print(ops['-'](50, 25)) 20 | -------------------------------------------------------------------------------- /chainedcomparison.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """chained comparison with all kind of operators""" 3 | a = 10 4 | print(1 < a < 50) 5 | print(10 == a < 20) 6 | -------------------------------------------------------------------------------- /codetofunction.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | ''' 3 | A simple way to convert arbitrary Python code into a function 4 | ''' 5 | 6 | import math # using sin, cos and sqrt for example 7 | 8 | ''' Takes a code string and returns a ready-to-use function ''' 9 | def compile_(s): 10 | code = """def f(x):\n return {}""".format(s) # wrap the string as a function f(x) 11 | scope = {"sin": math.sin, "cos": math.cos, "sqrt": math.sqrt} # define the scope for the code to use 12 | exec(code, scope) # execute code inside the given scope 13 | # f(x) gets defined inside %vis% 14 | return scope["f"] # now we only have to extract it and return 15 | 16 | f = compile_("x**2 + 2*sin(x)") 17 | print(f(10)) -------------------------------------------------------------------------------- /common_seq_method.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Run common method of big sequence of objects""" 3 | import operator 4 | 5 | 6 | class Foo(): 7 | def bar(self, *args, **kwargs): 8 | print('method bar works') 9 | 10 | 11 | sequence = [Foo() for i in range(5)] 12 | 13 | # in python3 map returns iterator so we must ask python to process elements by list() 14 | # in python2 map(operator.methodcaller('bar'), sequence) works perfectly 15 | list(map(operator.methodcaller('bar'), sequence)) 16 | 17 | # there is another way more understandable 18 | [f.bar() for f in sequence] 19 | -------------------------------------------------------------------------------- /concatenatestrings.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Concatenate long strings elegantly 3 | across line breaks in code""" 4 | 5 | my_long_text = ("We are no longer the knights who say Ni! " 6 | "We are now the knights who say ekki-ekki-" 7 | "ekki-p'tang-zoom-boing-z'nourrwringmm!") 8 | -------------------------------------------------------------------------------- /conditionalassignment.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Python has two ways to do conditional assignments 3 | 4 | The first is a fairly standard teranary style; 5 | if else 6 | 7 | The second method takes advantage of the fact that python's or is lazy. When 8 | an assignment is made if the first value is falsy (None is falsy), then it will 9 | automatically return the second value, even if that value is falsy. 10 | 11 | """ 12 | b = True 13 | print(True if b else False) 14 | 15 | b = None or False 16 | print(b) 17 | -------------------------------------------------------------------------------- /conditionalfunctioncall.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """calling different functions with same arguments based on condition""" 3 | def product(a, b): 4 | return a * b 5 | 6 | def subtract(a, b): 7 | return a - b 8 | 9 | b = True 10 | print((product if b else subtract)(1, 1)) 11 | -------------------------------------------------------------------------------- /contextmanagers.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Context managers are useful for automatically releasing resources once you are done with them.""" 3 | 4 | # common context manager that will close 5 | # a file when it has been read 6 | with open('README.md') as f: 7 | contents = f.read() 8 | 9 | 10 | # make your own context manager 11 | import contextlib 12 | 13 | @contextlib.contextmanager 14 | def unlock(resource): 15 | resource.locked = False 16 | try: 17 | yield 18 | finally: 19 | resource.locked = True 20 | 21 | 22 | # a resource that is locked 23 | class Resource: 24 | def __init__(self): 25 | self.locked = True 26 | 27 | resource = Resource() 28 | 29 | # test that it is indeed locked 30 | print(resource.locked) 31 | 32 | # call your 'unlock' context manager with your resource 33 | with unlock(resource): 34 | print(resource.locked) # check that it is unlocked 35 | 36 | # ensure it was re-locked when it left the 'unlock' context 37 | print(resource.locked) 38 | -------------------------------------------------------------------------------- /controlwhitespaces.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """control the whitespaces in string""" 3 | 4 | s = 'The Little Price' 5 | 6 | # justify string to be at least width wide 7 | # by adding whitespaces 8 | width = 20 9 | s1 = s.ljust(width) 10 | s2 = s.rjust(width) 11 | s3 = s.center(width) 12 | print(s1) # 'The Little Price ' 13 | print(s2) # ' The Little Price' 14 | print(s3) # ' The Little Price ' 15 | 16 | # strip whitespaces in two sides of string 17 | print(s3.lstrip()) # 'The Little Price ' 18 | print(s3.rstrip()) # ' The Little Price' 19 | print(s3.strip()) # 'The Little Price' 20 | -------------------------------------------------------------------------------- /copylist.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | import sys 3 | 4 | """a fast way to make a shallow copy of a list""" 5 | 6 | a = [1, 2, 3, 4, 5] 7 | print(a[:]) 8 | 9 | 10 | """adding an empty list yields a copy of initial list""" 11 | 12 | a = [1, 2, 3, 4, 5] 13 | print(a + []) # in python3, for small lists performs faster than a[:] 14 | 15 | 16 | """copy list by typecasting method""" 17 | 18 | a = [1, 2, 3, 4, 5] 19 | print(list(a)) 20 | 21 | 22 | """using the list.copy() method (python3 only)""" 23 | 24 | if sys.version_info.major == 3: 25 | a = [1, 2, 3, 4, 5] 26 | print(a.copy()) 27 | else: 28 | # in python2 there exists the `copy` builtin module 29 | from copy import copy 30 | a = [1, 2, 3, 4, 5] 31 | print(copy(a)) 32 | 33 | 34 | """copy nested lists using copy.deepcopy""" 35 | 36 | from copy import deepcopy 37 | 38 | l = [[1, 2], [3, 4]] 39 | 40 | l2 = deepcopy(l) 41 | print(l2) 42 | 43 | -------------------------------------------------------------------------------- /deck_as_list.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ How to use dunder methods to add behavior to objects. 4 | Here it's an example of how implement a french deck that can be used as a list""" 5 | 6 | import collections 7 | 8 | Card = collections.namedtuple('Card', ['rank', 'suit']) 9 | 10 | 11 | class Deck: 12 | 13 | ranks = [str(n) for n in range(2, 11)] + list('JQKA') 14 | suits = 'spades diamonds clubs hearts'.split() 15 | 16 | def __init__(self): 17 | self._cards = [Card(rank, suit) for suit in self.suits 18 | for rank in self.ranks] 19 | 20 | def __len__(self): 21 | return len(self._cards) 22 | 23 | def __getitem__(self, position): 24 | return self._cards[position] 25 | 26 | card_a = Card('A', 'spades') 27 | print(card_a) 28 | 29 | deck = Deck() 30 | len(deck) 31 | 32 | print(deck[0]) 33 | print(deck[-1]) 34 | for card in deck: 35 | print(card) 36 | -------------------------------------------------------------------------------- /dictdefaultvalue.py: -------------------------------------------------------------------------------- 1 | """ 2 | When update value in a dict based on the old value, we usually check whether 3 | the key is in the dict. But with `dict.setdefault`, `dict.get` and 4 | `collections.defaultdict` the code can be shorter and cleaner. 5 | 6 | Before: 7 | >>> d = {} 8 | >>> if 'a' not in d: # update a list 9 | ... d['a'] = [] 10 | ... 11 | >>> d['a'].append(1) 12 | >>> 13 | >>> if 'b' not in d: # update an integer 14 | ... d['b'] = 0 15 | ... 16 | >>> d['b'] += 1 17 | 18 | Now: 19 | >>> d = {} 20 | >>> d.setdefault('a', []).append(1) 21 | >>> d['b'] = d.get('b', 0) + 1 22 | """ 23 | 24 | """ builtin dict """ 25 | d = {} 26 | d.setdefault('a', []).append(1) 27 | d['b'] = d.get('b', 0) + 1 28 | 29 | print(d) 30 | 31 | 32 | """ with collections.defaultdict """ 33 | from collections import defaultdict 34 | 35 | d = defaultdict(list) 36 | d['a'].append(1) 37 | 38 | print(d) 39 | -------------------------------------------------------------------------------- /dictionaryget.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """returning None or default value, when key is not in dict""" 3 | d = {'a': 1, 'b': 2} 4 | 5 | print(d.get('c', 3)) 6 | 7 | -------------------------------------------------------------------------------- /dictsortbyvalue.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ Sort a dictionary by its values with the built-in sorted() function and a 'key' argument. """ 3 | 4 | d = {'apple': 10, 'orange': 20, 'banana': 5, 'rotten tomato': 1} 5 | print(sorted(d.items(), key=lambda x: x[1])) 6 | 7 | 8 | """ Sort using operator.itemgetter as the sort key instead of a lambda""" 9 | 10 | 11 | from operator import itemgetter 12 | 13 | 14 | print(sorted(d.items(), key=itemgetter(1))) 15 | 16 | 17 | """Sort dict keys by value""" 18 | 19 | 20 | print(sorted(d, key=d.get)) 21 | -------------------------------------------------------------------------------- /dictswapkeysvalues.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Swaps keys and values in a dict""" 3 | 4 | _dict = {"one": 1, "two": 2} 5 | # make sure all of dict's values are unique 6 | assert len(_dict) == len(set(_dict.values())) 7 | reversed_dict = {v: k for k, v in _dict.items()} -------------------------------------------------------------------------------- /exec.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """exec can be used to execute Python code during runtime 3 | variables can be handed over as a dict 4 | """ 5 | exec("print('Hello ' + s)", {'s': 'World'}) 6 | -------------------------------------------------------------------------------- /extendediterableunpacking.py3: -------------------------------------------------------------------------------- 1 | """allows collecting not explicitly assigned values into 2 | a placeholder variable""" 3 | 4 | a, *b, c = range(10) 5 | print(a, b, c) 6 | 7 | """advanced example""" 8 | 9 | [(c, *d, [*e]), f, *g] = [[1, 2, 3, 4, [5, 5, 5]], 6, 7, 8] 10 | print(c, d, e, f, g) 11 | -------------------------------------------------------------------------------- /flattenlist.py: -------------------------------------------------------------------------------- 1 | """ 2 | Deep flattens a nested list 3 | 4 | Examples: 5 | >>> list(flatten_list([1, 2, [3, 4], [5, 6, [7]]])) 6 | [1, 2, 3, 4, 5, 6, 7] 7 | >>> list(flatten_list(['apple', 'banana', ['orange', 'lemon']])) 8 | ['apple', 'banana', 'orange', 'lemon'] 9 | """ 10 | 11 | 12 | # Flatten list of lists 13 | 14 | a = [[1, 2], [3, 4]] 15 | 16 | # Solutions: 17 | 18 | print([x for _list in a for x in _list]) 19 | 20 | import itertools 21 | print(list(itertools.chain(*a))) 22 | 23 | print(list(itertools.chain.from_iterable(a))) 24 | 25 | print(sum(a, [])) 26 | 27 | -------------------------------------------------------------------------------- /flattenlist.py2: -------------------------------------------------------------------------------- 1 | L = [1, 2, [3, 4], [5, 6, [7]]] 2 | 3 | from compiler.ast import flatten 4 | flatten(L) 5 | 6 | a = [[1, 2], [3, 4]] 7 | print(reduce(lambda x, y: x+y, a)) -------------------------------------------------------------------------------- /flattenlist.py3: -------------------------------------------------------------------------------- 1 | L = [1, 2, [3, 4], [5, 6, [7]]] 2 | 3 | def flatten(L): 4 | for item in L: 5 | if isinstance(item, list): 6 | yield from flatten(item) 7 | else: 8 | yield item 9 | 10 | flatten(L) 11 | -------------------------------------------------------------------------------- /forelse.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """else gets called when for loop does not reach break statement""" 3 | a = [1, 2, 3, 4, 5] 4 | for el in a: 5 | if el == 0: 6 | break 7 | else: 8 | print('did not break out of for loop') 9 | 10 | -------------------------------------------------------------------------------- /ifelsecommentswitch.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """ 3 | comment blocks can be turn on and off 4 | in one character switch when preceded by #""" 5 | 6 | #''' #< toggling off this # turns the block as a comment (it wasn't, line was mute) 7 | print("you saw me!") 8 | #''' 9 | 10 | print("catched!") 11 | 12 | """ 13 | second example is the equivalent 14 | of C prepropressors #ifdef 0 / #ifdef 1 comment styles: 15 | """ 16 | 17 | #''' < toggling this # will comment the next block, 18 | print("you saw me now you don't see me") 19 | '''# which will stop here, where it was previously beginning, hence turning it in the ending block tag 20 | print("you didn't see me, now you do !") 21 | #''' # and so, it uncomments the one below 22 | 23 | print('continue...') 24 | -------------------------------------------------------------------------------- /keydefaultdict.py: -------------------------------------------------------------------------------- 1 | """ 2 | keydefaultdict with where the function receives the key. 3 | """ 4 | from collections import defaultdict 5 | 6 | 7 | class keydefaultdict(defaultdict): 8 | def __missing__(self, key): 9 | if self.default_factory is None: 10 | raise KeyError(key) 11 | else: 12 | ret = self[key] = self.default_factory(key) 13 | return ret 14 | 15 | 16 | def pow2(n): 17 | return 1 << n 18 | 19 | d = keydefaultdict(pow2) 20 | print(d[1]) 21 | print(d[3]) 22 | print(d[10]) 23 | print(d) 24 | -------------------------------------------------------------------------------- /listtocommaseparated.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """converts list to comma separated string""" 3 | 4 | items = ['foo', 'bar', 'xyz'] 5 | 6 | print (','.join(items)) 7 | 8 | """list of numbers to comma separated""" 9 | numbers = [2, 3, 5, 10] 10 | 11 | print (','.join(map(str, numbers))) 12 | 13 | """list of mix data""" 14 | data = [2, 'hello', 3, 3.4] 15 | 16 | print (','.join(map(str, data))) 17 | 18 | 19 | -------------------------------------------------------------------------------- /loopoverlappingdicts.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """loop over dicts that share (some) keys in Python2""" 3 | 4 | dctA = {'a': 1, 'b': 2, 'c': 3} 5 | dctB = {'b': 4, 'c': 3, 'd': 6} 6 | 7 | for ky in set(dctA) & set(dctB): 8 | print(ky) 9 | -------------------------------------------------------------------------------- /loopoverlappingdicts.py3: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | dctA = {'a': 1, 'b': 2, 'c': 3} 3 | dctB = {'b': 4, 'c': 3, 'd': 6} 4 | 5 | """loop over dicts that share (some) keys in Python3""" 6 | for ky in dctA.keys() & dctB.keys(): 7 | print(ky) 8 | 9 | """loop over dicts that share (some) keys and values in Python3""" 10 | for item in dctA.items() & dctB.items(): 11 | print(item) 12 | -------------------------------------------------------------------------------- /maxsplit.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """split a string max times""" 3 | string = "a_b_c" 4 | print(string.split("_", 1)) 5 | 6 | 7 | """use maxsplit with arbitrary whitespace""" 8 | 9 | s = "foo bar foobar foo" 10 | 11 | print(s.split(None, 2)) 12 | -------------------------------------------------------------------------------- /merge_dict.py: -------------------------------------------------------------------------------- 1 | """merge dict's""" 2 | 3 | d1 = {'a': 1} 4 | d2 = {'b': 2} 5 | 6 | d1.update(d2) 7 | print(d1) 8 | -------------------------------------------------------------------------------- /merge_dict.py3: -------------------------------------------------------------------------------- 1 | """merge dict's""" 2 | 3 | d1 = {'a': 1} 4 | d2 = {'b': 2} 5 | 6 | print({**d1, **d2}) 7 | 8 | print(dict(d1.items() | d2.items())) -------------------------------------------------------------------------------- /metatable.py: -------------------------------------------------------------------------------- 1 | """ 2 | metatable with where the function receives the dictionary and key. 3 | """ 4 | from collections import defaultdict 5 | 6 | 7 | class metatable(defaultdict): 8 | 9 | def __missing__(self, key): 10 | if self.default_factory is None: 11 | raise KeyError(key) 12 | else: 13 | ret = self[key] = self.default_factory(self, key) 14 | return ret 15 | 16 | 17 | def fib(d, n): 18 | if n == 0 or n == 1: 19 | return n 20 | return d[n - 1] + d[n - 2] 21 | 22 | d = metatable(fib) 23 | print(d[1]) 24 | print(d[3]) 25 | print(d[10]) 26 | print(d) 27 | -------------------------------------------------------------------------------- /minmaxindex.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find Index of Min/Max Element. 3 | """ 4 | 5 | lst = [40, 10, 20, 30] 6 | 7 | 8 | def minIndex(lst): 9 | return min(range(len(lst)), key=lst.__getitem__) # use xrange if < 2.7 10 | 11 | 12 | def maxIndex(lst): 13 | return max(range(len(lst)), key=lst.__getitem__) # use xrange if < 2.7 14 | 15 | print(minIndex(lst)) 16 | print(maxIndex(lst)) 17 | -------------------------------------------------------------------------------- /namedformatting.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """easy string formatting using dicts""" 3 | 4 | d = {'name': 'Jeff', 'age': 24} 5 | print("My name is %(name)s and I'm %(age)i years old." % d) 6 | 7 | """for .format, use this method""" 8 | 9 | d = {'name': 'Jeff', 'age': 24} 10 | print("My name is {name} and I'm {age} years old.".format(**d)) 11 | 12 | """alternate .format method""" 13 | print("My name is {} and I'm {} years old.".format('Jeff','24')) 14 | 15 | """dict string formatting""" 16 | c = {'email': 'jeff@usr.com', 'phone': '919-123-4567'} 17 | print('My name is {0[name]}, my email is {1[email]} and my phone number is {1[phone]}'.format(d, c)) 18 | 19 | """object string formatting""" 20 | class Person: 21 | pass 22 | me = Person() 23 | me.name = 'Jeff' 24 | me.email = 'jeff@usr.com' 25 | me.phone = '919-123-4567' 26 | print('My name is {me.name}, my email is {me.email} and my phone number is {me.phone}'.format(me=me)) -------------------------------------------------------------------------------- /namedformatting.py3: -------------------------------------------------------------------------------- 1 | """f-string (Python 3.6+)""" 2 | name = "Jeff" 3 | age = 24 4 | print(f"My name is {name} and I'm {age} years old.") -------------------------------------------------------------------------------- /nested_functions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """nested functions""" 3 | def addBy(val): 4 | def func(inc): 5 | return val + inc 6 | return func 7 | 8 | addFive = addBy(5) 9 | print(addFive(4)) 10 | 11 | addThree = addBy(3) 12 | print(addThree(7)) 13 | -------------------------------------------------------------------------------- /objgetnamedattribute.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """ Return the value of the named attribute of an object """ 3 | class obj(): 4 | attr = 1 5 | 6 | foo = "attr" 7 | print(getattr(obj, foo)) 8 | -------------------------------------------------------------------------------- /rawinputintegers.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | Convert raw string integer inputs to integers 5 | """ 6 | 7 | str_input = "1 2 3 4 5 6" 8 | 9 | print("### Input ###") 10 | print(str_input) 11 | 12 | int_input = map(int, str_input.split()) 13 | 14 | print("### Output ###") 15 | print(list(int_input)) 16 | -------------------------------------------------------------------------------- /removeduplicatefromlist.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """remove duplicate items from list. note: does not preserve the original list order""" 3 | 4 | items = [2, 2, 3, 3, 1] 5 | 6 | newitems2 = list(set(items)) 7 | print(newitems2) 8 | 9 | """remove dups and keep order""" 10 | 11 | from collections import OrderedDict 12 | 13 | items = ["foo", "bar", "bar", "foo"] 14 | 15 | print(list(OrderedDict.fromkeys(items).keys())) 16 | -------------------------------------------------------------------------------- /reverselist.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """reversing list with special case of slice step param""" 3 | a = [5, 4, 3, 2, 1] 4 | print(a[::-1]) 5 | 6 | """iterating over list contents in reverse efficiently.""" 7 | for ele in reversed(a): 8 | print(ele) 9 | -------------------------------------------------------------------------------- /reversestring.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """reversing string with special case of slice step param""" 4 | 5 | a = 'abcdefghijklmnopqrstuvwxyz' 6 | print(a[::-1]) 7 | 8 | 9 | """iterating over string contents in reverse efficiently.""" 10 | 11 | for char in reversed(a): 12 | print(char) 13 | 14 | """reversing an integer through type conversion and slicing.""" 15 | 16 | num = 123456789 17 | print(int(str(num)[::-1])) 18 | -------------------------------------------------------------------------------- /setglobalvariables.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """set global variables from dict""" 3 | 4 | d = {'a': 1, 'b': 'var2', 'c': [1, 2, 3]} 5 | globals().update(d) 6 | print(a, b, c) 7 | -------------------------------------------------------------------------------- /setoperators.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Python provides usual set operator""" 3 | a = set(['a', 'b', 'c', 'd']) 4 | b = set(['c', 'd', 'e', 'f']) 5 | c = set(['a', 'c']) 6 | 7 | # Intersection 8 | print(a & b) 9 | 10 | # Subset 11 | print(c < a) 12 | 13 | # Difference 14 | print(a - b) 15 | 16 | # Symmetric Difference 17 | print(a ^ b) 18 | 19 | # Union 20 | print(a | b) 21 | 22 | """using methods instead of operators which take any iterable as a second arg""" 23 | 24 | a = {'a', 'b', 'c', 'd'} 25 | b = {'c', 'd', 'e', 'f'} 26 | c = {'a', 'c'} 27 | 28 | print(a.intersection(["b"])) 29 | 30 | print(a.difference(["foo"])) 31 | 32 | print(a.symmetric_difference(["a", "b", "e"])) 33 | 34 | print(a.issuperset(["b", "c"])) 35 | 36 | print(a.issubset(["a", "b", "c", "d", "e", "f"])) 37 | 38 | print(a.isdisjoint(["y", 'z'])) 39 | 40 | print(a.union(["foo", "bar"])) 41 | 42 | a.intersection_update(["a", "c", "z"]) 43 | print(a) 44 | -------------------------------------------------------------------------------- /socketmsghandling.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import functools 3 | 4 | ConnectionRefusedError = socket.error 5 | 6 | msgs = [] 7 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 8 | try: 9 | conn = s.connect(('localhost', 80)) 10 | # normal way 11 | # while True: 12 | # msg = coon.recv(1024) 13 | # if recv: 14 | # msgs.append(msg) 15 | # else: # when no msg come, break 16 | # break 17 | 18 | # hack way with iter and functools.partial 19 | # this circle will auto break when msg is empty '' 20 | for msg in iter(functools.partial(conn.recv, 1024), b''): 21 | msgs.append(msg) 22 | except (socket.error, ConnectionRefusedError): 23 | pass -------------------------------------------------------------------------------- /sortlistkeepindices.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Sort a list and store previous indices of values""" 3 | 4 | # enumerate is a great but little-known tool for writing nice code 5 | 6 | l = [4, 2, 3, 5, 1] 7 | print("original list: ", l) 8 | 9 | values, indices = zip(*sorted((a, b) for (b, a) in enumerate(l))) 10 | 11 | # now values contains the sorted list and indices contains 12 | # the indices of the corresponding value in the original list 13 | 14 | print("sorted list: ", values) 15 | print("original indices: ", indices) 16 | 17 | # note that this returns tuples, but if necessary they can 18 | # be converted to lists using list() 19 | -------------------------------------------------------------------------------- /stepslice.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """stepwise slicing of arrays""" 3 | a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 4 | print(a[::3]) 5 | -------------------------------------------------------------------------------- /switch_case_statments_with_dict.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """lightweight switch statement""" 3 | a = { 4 | True: 1, 5 | False: -1, 6 | None: 0 7 | } 8 | print(a.get(False, 0)) 9 | 10 | """works with functions as well""" 11 | def add(a, b): 12 | return a + b 13 | 14 | def subtract(a, b): 15 | return a - b 16 | 17 | b = { 18 | '+': add, 19 | '-': subtract 20 | } 21 | 22 | print(b['+'](1, 1)) 23 | 24 | """ 25 | 26 | ---- Other Way ---- 27 | Switch/Case statments with Dictionaries 28 | Based on Dan Bader video: https://www.youtube.com/watch?v=gllUwQnYVww 29 | 30 | """ 31 | 32 | def traditional(operator, x , y): 33 | if operator == 'add': 34 | return x + y 35 | elif operator == 'sub': 36 | return x - y 37 | elif operator == 'mul': 38 | return x * y 39 | elif operator == 'div': 40 | return x / y 41 | 42 | 43 | def with_dict(operator, x ,y): 44 | return { 45 | 'add' : lambda: x + y, 46 | 'sub' : lambda: x - y, 47 | 'mul' : lambda: x * y, 48 | 'div' : lambda: x / y, 49 | }.get(operator, lambda: None)() 50 | -------------------------------------------------------------------------------- /transpose.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """transpose 2d array [[a,b], [c,d], [e,f]] -> [[a,c,e], [b,d,f]]""" 3 | 4 | original = [['a', 'b'], ['c', 'd'], ['e', 'f']] 5 | transposed = zip(*original) 6 | print(list(transposed)) 7 | -------------------------------------------------------------------------------- /tree.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """ 3 | See description here 4 | https://gist.github.com/hrldcpr/2012250 5 | """ 6 | 7 | from collections import defaultdict 8 | 9 | tree = lambda: defaultdict(tree) 10 | 11 | 12 | users = tree() 13 | users['harold']['username'] = 'chopper' 14 | users['matt']['password'] = 'hunter2' 15 | -------------------------------------------------------------------------------- /tryelse.py: -------------------------------------------------------------------------------- 1 | """ You can have an 'else' clause with try/except. 2 | It gets excecuted if no exception is raised. 3 | This allows you to put less happy-path code in the 'try' block so you can be 4 | more sure of where a caught exception came from.""" 5 | 6 | try: 7 | 1 + 1 8 | except TypeError: 9 | print("Oh no! An exception was raised.") 10 | else: 11 | print("Oh good, no exceptions were raised.") 12 | -------------------------------------------------------------------------------- /unique_by_attr.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """ 3 | If we have some sequence of objects and want to remove items with the same attribute value 4 | Python creates a dict, where keys are value if attribute (bar in our case), values are object of the sequence. 5 | After that the dict is transformed back to list 6 | Note: in result we save the last from repeating elements (item2 in our case)! 7 | """ 8 | 9 | 10 | class Foo(object): 11 | def __init__(self, value): 12 | self.bar = value 13 | 14 | def __eq__(self, other): 15 | return self.bar == getattr(other, 'bar') 16 | 17 | def __hash__(self): 18 | return int(self.bar) 19 | 20 | def __repr__(self): 21 | return '{}'.format(self.bar) 22 | 23 | item1 = Foo(15) 24 | item2 = Foo(15) 25 | item3 = Foo(5) 26 | 27 | lst = [item1, item2, item3] 28 | 29 | 30 | print(set(lst)) 31 | 32 | # original 33 | unique_lst = list({getattr(obj, 'bar'): obj for obj in lst}.values()) 34 | print(unique_lst) # [item2, item3] 35 | -------------------------------------------------------------------------------- /valueswapping.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | # Type of variable: Number 3 | a, b = 5, 10 4 | print(a, b) 5 | a, b = b, a 6 | print(a, b) 7 | # Type of variable: List 8 | myList = [1, 2, 3, 4, 5] 9 | print("Initial Array :", myList) 10 | myList[0], myList[1] = myList[1], myList[0] 11 | print("Swapped Array :", myList) 12 | -------------------------------------------------------------------------------- /whileelse.py: -------------------------------------------------------------------------------- 1 | """ You can have an else clause with a while. Works like for-else. 2 | When break is encountered, it exits the loop without executing else. """ 3 | 4 | i = 5 5 | 6 | while i > 1: 7 | print("Whil-ing away!") 8 | i -= 1 9 | if i == 3: 10 | break 11 | else: 12 | print("Finished up!") 13 | --------------------------------------------------------------------------------