**kwargs:

We write a function func_call_api to call api_function which are not maintainable by us.

def api_function(a, b, c):
    print a
    print b
    print c
def func_call_api(a, b, c):
    api_function(a=a+1, b=b+1, c=c+1)
func_call_api(a=1, b=2, c=3)

Once the api_function was modified have more input in the parameters, we need to change our code:

def api_function(a, b, c, d, e):
    print a
    print b
    print c
    print d
    print e
def func_call_api(a, b, c, d, e):
    api_function(a=a+1, b=b+1, c=c+1, d, e)
func_call_api(a=1, b=2, c=3, d=4, e=5)

However, use **kwargs can save a bit time for us:

def api_function(a, b, c, d, e):
    print a
    print b
    print c
    print d
    print e
def func_call_api(a, b, c, **kwargs):
    api_function(a=a, b=b, c=c, **kwargs)
func_call_api(a=1, b=2, c=3, d=4, e=5)

Reflection/Introspection

Reflection: find out the type/attribute/method/class of an object at run time. (while some programmers like compile time type check.)

Python use inspect module to do it.

see python/others/inspect.py

Built-in Functions

zip():

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x = list(x2) and y = list(y2)
True

Read input from STDIN. Print output to STDOUT

(ongoing)

a, b = 1, 2 (Simultaneous assignment?)

An useless fun example to work out:

>>> a = [0,0,0,0]
>>> i, a[i], i, a[i] = range(4)
>>> a
[1, 0, 3, 0]

Someone says that:

“simultaneous assignment” doesn’t even appear in the Python documentation. a, b = 1, 2 is just shorthand for (a, b) = (1, 2), which is called sequence unpacking.

Accessing the index for loops

for idx, val in enumerate(ints):
    print(idx, val)

Two-dimensional array

# Creates a list containing 5 lists, each of 8 items, all set to 0
lists, items = 5, 8
M = [[0 for y in range(items)] for x in range(lists)]
M[4][7] = 9

Finding the index of an item in a list

>>> ["foo", "bar", "baz"].index("bar")
1

ASCII value of a character

>>> ord('a')
97
>>> chr(97)
'a'
>>> chr(ord('a') + 3)
'd'
>>>

Scope of variable in for loop

The for loop iterates over all the numbers in range(10), that is, [0,1,2,3,4,5,6,7,8,9]. That you change the current value of i has no effect on the next value in the range.

You can change the value of i with a while loop.

i = 0
while i < 10:
    # do stuff and manipulate `i` as much as you like
    if i==5:
        i+=3

    print i

    # don't forget to increment `i` manually
    i += 1

Add binary numbers

bin and int are very useful here:

a = '001'
b = '011'

c = bin(int(a,2) + int(b,2))
# 0b100

int allows you to specify what base the first argument is in when converting from a string (in this case two), and bin converts a number back to a binary string.

Or definde a function:

def bin_add(*args): return bin(sum(int(x, 2) for x in args))[2:]
>>> bin_add('1', '10', '100')
'111'

if A vs if A is not None:

if A:

will call either A.__nonzero__() or A.__len__(). If a class defines neither len() nor nonzero(), all its instances are considered true.

if A is not None:

compares only the reference A with None to see whether it is the same or not.

Python if x is not None or if not x is None?

There’s no performance difference, as they compile to the same bytecode:

Python 2.6.2 (r262:71600, Apr 15 2009, 07:20:39)
>>> import dis
>>> def f(x):
...    return x is not None
...
>>> dis.dis(f)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE
>>> def g(x):
...   return not x is None
...
>>> dis.dis(g)
  2           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               0 (None)
              6 COMPARE_OP               9 (is not)
              9 RETURN_VALUE

Stylistically, I try to avoid not x is y. Although the compiler will always treat it as not (x is y), a human reader might misunderstand the construct as (not x) is y. If I write x is not y then there is no ambiguity.

Reset global variable

If you don’t need the GLOBAL_VARIABLE anymore you could use:

del GLOBAL_VARIABLE

If you want a empty list:

del GLOBAL_VARIABLE[:]

One line if-then statement

'Yes' if fruit == 'Apple' else 'No'

When is “i += x” different from “i = i + x” in Python?

As a concrete example:

a = [1, 2, 3]
b = a
b += [1, 2, 3]
print a  #[1, 2, 3, 1, 2, 3]
print b  #[1, 2, 3, 1, 2, 3]

compared to:

a = [1, 2, 3]
b = a
b = b + [1, 2, 3]
print a #[1, 2, 3]
print b #[1, 2, 3, 1, 2, 3]

String

Comparing strings either ‘==’ or ‘is’ sometimes produce a different result?

>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False

Since a and b has a different address in memory.

is is identity testing, == is equality testing.

In other words: is is the id(a) == id(b)

Sorting list based on the length of the string

xs.sort(key = len)

You can also use the built-in sorted function rather than the list.sort method, which creates a new list rather than sorting the existing one in-place:

print sorted(xs, key=len)

Trim whitespace (including tabs)

Whitespace on the both sides:

s = "  \t a string example\t  "
s = s.strip()
s = s.rstrip() # right side
s = s.lstrip() # left side

You can provide an argument to strip arbitrary characters to any of these functions like this:

``` python
s = s.strip(' \t\n\r')

This will strip any space, \t, \n, or \r characters from the left-hand side, right-hand side, or both sides of the string.

If you want to also remove characters from the middle of a string, try re.sub:

import re
print re.sub('[\s+]', '', s)

That should print out:

astringexample

Remove all whitespace in a string

If you want to remove leading and ending spaces, use str.strip():

sentence = ' hello  apple'
sentence.strip()
>>> 'hello  apple'

If you want to remove all spaces, use str.replace():

sentence = ' hello  apple'
sentence.replace(" ", "")
>>> 'helloapple'

If you want to remove duplicated spaces, use str.split():

sentence = ' hello  apple'
" ".join(sentence.split())
>>> 'hello apple'

Convert list to string

By using ''.join

list1 = ['1', '2', '3']
str1 = ''.join(list1)

Or if the list is of integers, convert the elements before joining them.

list1 = [1, 2, 3]
str1 = ''.join(str(e) for e in list1)

Delete a character from a string

In Python, strings are immutable, so you have to create a new string. You have a few options of how to create the new string. If you want to remove the ‘M’ wherever it appears:

newstr = oldstr.replace("M", "")

Replace all non-alphanumeric characters in a string

import re

s = re.sub('[^0-9a-zA-Z]+', '*', s)

usage:

>>> re.sub('[^0-9a-zA-Z]+', '*', 'h^&ell`.,|o w]{+orld')
'h*ell*o*w*orld'

Dictionary

Iterate dictionary by index

You can iterate over keys and get values by keys:

for key in dict.iterkeys():
    print key, dict[key]

You can iterate over keys and corresponding values:

for key, value in dict.iteritems():
    print key, value

You can use enumerate if you want indexes (remember that dictionaries don’t have an order):

>>> for index, key in enumerate(dict):
...     print index, key
...
0 orange
1 mango
2 apple
>>>

Index a dictionary

Dictionaries are unordered in Python. If you do not care about the order of the entries and want to access the keys or values by index anyway, you can use d.keys()[i] and d.values()[i] or d.items()[i]. (Note that these methods create a list of all keys, values or items, respectively. So if you need them more then once, store the list in a variable to improve performance.)

>>> dict
{'blue': 5, 'yellow': 2, 'red': 3}
>>> dict.keys()[0]
'blue'
>>> dict.values()[2]
3
>>> dict.items()[1]
('yellow', 2)

If you do care about the order of the entries, starting with Python 2.7 you can use collections.orderdDict. Or use a list of pairs

l = [("blue", "5"), ("red", "6"), ("yellow", "8")]

Filter a dictionary

d = dict((k, v) for k, v in d.iteritems() if v > 0)

In Python 2.7 and up, there’s nicer syntax for this:

d = {k: v for k, v in d.items() if v > 0}

Note that this is not strictly a filter because it does create a new dictionary.

Reference

How do you read from stdin in Python?
Python 标准输出 sys.stdout 重定向