<Python> The WAY of Python

1. with-as (context-manager)

Example:

with function() as instance:
    #do something

Codes above do the following:

Let instance = function(), where function returns an instantiation of some object, and this object has defined method __enter__() and __exit__().

Hence, before do something, execute __enter__(),

and after do something, execute __exit__() which are defined in the class of instance.

 

For detail, see http://blog.csdn.net/suwei19870312/article/details/23258495

 

 

2. basic data type manipulation

Example:

[1] + [2] -> [1, 2]

[1] * 3 = [1, 1, 1] (or written as [1 for _ in range(3)])

#to be supplemented

 

 

3. loop-else

Example:

 1 from random import randint
 2 
 3 # Generates a number from 1 through 10 inclusive
 4 random_number = randint(1, 10)
 5 
 6 guesses_left = 3
 7 # Start your game!
 8 while guesses_left > 0:
 9     guess = int(raw_input())
10     if guess == random_number:
11         print 'You win!'
12         break
13     guesses_left -= 1
14 else:  # run if while ends without break
15     print "You lose."

As shown above, a no-indent else following a while block will be executed only if the block ended itself without internal break. This can also be used on for-loop.

 

 

4. zip()

Example:

1 a = [1, 2, 3]
2 b = [4, 5, 6]
3 
4 zip(a, b) # [(1, 4), (2, 5), (3, 6)]
5 zip(*zip(a, b)) == [a, b] # True

zip will create pairs of elements when passed two lists, and will stop at the end of the shorter list.

zip can handle three or more lists as well, and you can get the original input of zip by zip(*zip(original_input))!

1 list_a = [1, 2, 3]
2 list_b = [4, 5, 6]
3 
4 for a, b in zip(list_a, list_b):
5     # Add your code here!
6     print max(a, b)

It's also common to iterate over two or multiple lists at once. This is where the built-in zip function comes in handy.

 

 

5. string translator prefixes

u"string" => use unicode to decode string (however, Python 3 handles unicode as regular strings)

r"string" => view string as raw characters, avoiding translation (useful in regex expression)

 

 

6. filter()

Example:

def purify(lst): # only even number last
    return filter(lambda x: x % 2 == 0, lst)

filter(condition, <mutable sequence type>)

 

 

7. bitwise operator

1 print 5 >> 4  # Right Shift
2 print 5 << 1  # Left Shift
3 print 8 & 5   # Bitwise AND
4 print 9 | 4   # Bitwise OR
5 print 12 ^ 42 # Bitwise XOR
6 print ~88     # Bitwise NOT

 

 

8. yield

def fab(max): 
    n, a, b = 0, 0, 1 
    while n < max: 
        yield b 
        a, b = b, a + b 
        n = n + 1

 >>> for n in fab(5): 
 ...     print n 
 ... 
 1 
 1 
 2 
 3 
 5

yield turns a function into a generator

 

 

9. type() and isinstance()

>>> lst = [1, 2, 3]
>>> type(lst)
<type 'list'>
>>> isinstance(lst, list)
True

isinstance(object, class-or-type-or-tuple) -> bool
Return whether an object is an instance of a class or of a subclass thereof.
With a type as second argument, return whether that is the object's type.
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for isinstance(x, A)
or isinstance(x, B) or ... (etc.).

 

 

10. sys.stdout.write() and sys.stdout.flush()

import sys

for i in range(100):
    sys.stdout.write("Processing...%d\r" % i)
    sys.stdout.flush()
    # do something

This output to the same line overwriting previous output. Useful when you have iterating output with similar content, especially process monitoring. Remember to add '\r' to the end of output string. '\r' is called the 'carriage return' which solely put the caret back at the start of the current line. It does not erase anything.

 

 

11. About Numpy efficiency

import numpy as np

# use the following
A = list()
for i in range(1000000):
    A.append(i)
A = np.array(A)

# instead of
A = np.array([])
for i in range(1000000):
    np.append(A, i)

np.append is really slow compared with regular list.append method (above 100 times slower). Avoid using some numpy methods, for instance, np.append and np.concatenate, in massive iteration if there are alternative regular solutions.

 

 

12. Disable greedy matching of regex

One of the default regex matching strategies in Python package `re' is greedy matching, that is, for a given pattern, match as longer string as possible, but sometimes, we want to match as shorter and as more strings as possible.

For example, to extract content from all of the <td> tags below:

<table>
    <tr>
        <td>Love me like you do</td>
        <td>Outside</td>
        <td>On my mind</td>
    </tr>
</table>

It is natrual to use the following code:

re.search("(?<=[<]td[>]).*(?=[<][/]td[>])", html)

However, the quantifier star (*) is greedy just like other regex quantifiers which try to match strings as long as possible. Apparently, the search result in this case would be,

string = "Love me like you do</td><td>Outside</td><td>On my mind"

which is not what we want. To achieve our goal, append the question symbol (?) right after the greedy quantifier, just like below:

# .*  ->  .*?
re.search("(?<=[<]td[>]).*?(?=[<][/]td[>])", html)

# {3, 5}  -> {3, 5}?
re.search("a{3, 5}?", string)

The regex now matches strings as short and as many as possible.

 

 

13. Tuple delaration

# When there is only one element that you want to put into the tuple, use
t = (variable,)

# Instead of
t = (variable)
# This is not recognized as a tuple delaration

# And
t = tuple(variable)
# Because when variable is a string, tuple() would split it up by character

 

 

14. Iterator & Generator

# Use iterator to find out if s is a subsequence of t
def isSubsequence(self, s, t):
    t = iter(t)
    return all(c in t for c in s)

# Use generator to improve speed
for i in xrange(10000):
    pass

 

 

15. Odd number

# Use
num & 1 == 1

# instead of
num % 2 == 1

 

16. Assertion

# make sure some condition is met (second expression is optional)
assert len(a) > 10, 'array length too short'

# which is equivalent to
if __debug__:
    if not len(a) > 10: raise AssertionError('array length too short')

 

17. Enumerate

values = ['apple', 'banana', 'grapes', 'pear']

# instead of using
for i, value in zip(range(len(values)), values):
     print i, value

# we can simply use
for i, value in enumerate(values):
     print i, value
# Output:
# 0 apple
# 1 banana
# 2 grapes
# 3 pear

# in addition, we can specify where to start the index i
for i, value in enumerate(values, 1):
     print i, value
# Output:
# 1 apple
# 2 banana
# 3 grapes
# 4 pear

 

18. Asterisk(*)

The single star * unpacks the sequence/collection into positional arguments, so you can do this:

def sum(a, b):
    return a + b
values = (1, 2)
s = sum(*values)

This will unpack the tuple so that it actually executes as:

s = sum(1, 2)

The double star ** does the same, only using a dictionary and thus named arguments:

values = { 'a': 1, 'b': 2 }
s = sum(**values)

You can also combine:

def sum(a, b, c, d):
    return a + b + c + d

values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)

will execute as:

s = sum(1, 2, c=10, d=15)

Additionally you can define functions to take *x and **y arguments, this allows a function to accept any number of positional and/or named arguments that aren't specifically named in the declaration.

Also see section 4.7.4 - Unpacking Argument Lists of the Python documentation.

 

posted @ 2016-09-01 22:13  m.Just  阅读(221)  评论(0)    收藏  举报