< Python > Some python tricks you may never use But you should know

namedtuple

If you are too lazy to create a class but you still want to use a variable that can act as a class object, then you should use namedtuple:

1
2
3
4
from collections import namedtuple
user = namedtuple('u', [1, 2, 3])
ztq = user(a='a', b='b',c='c')
print(ztq.a, ztq.b, ztq.c)

result:

1
(1,2,3)

decorator

If you are too lazy to change a function from inner code but you still want to add some new features to a function, you should use decorator. For example, if you want to print “hello” when you add two numbers:

1
2
3
4
5
6
7
8
9
10
11
12
13
def hello(fn):
def wrapper(*args, **kwargs):
aa = fn(*args, **kwargs)
print('hello')
return aa
return wrapper

def my_add(a,b):
return a+b
my_add = hello(my_add)

aa = my_add(10,10)
print(aa)

result:

1
2
hello
20

or you can use operator “@” to implement your function elegantly:

1
2
3
4
5
6
7
8
9
10
11
12
13
def hello(fn):
def wrapper(*args, **kwargs):
aa = fn(*args, **kwargs)
print('hello')
return aa
return wrapper

@hello
def my_add(a,b):
return a+b

aa = my_add(10,10)
print(aa)

enumerate

If you are too lazy to count the index of a list in a loop but you still need the index, then you should use enumerate:

1
2
3
a = ['a', 'b', 'c']
for ind, item in a:
print(ind, item)

result:

1
2
3
(0, 'a')
(1, 'b')
(2, 'c')

iterator

If you are too lazy to get the every elements in a list by index but you still want to get every element in order, then you should use iterator:

1
2
3
4
5
6
7
8
9
10
11
12
13
def inc():
for i in range(10):
yield i
x = inc()

print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))

result:

1
2
3
4
5
6
7
8
0
1
2
3
4
5
6
7

Do not easily copy object in python

If you are too lazy to get deepcopy a other object but you still want get a copy of a exists one, then you many creating a bug in you code!
In python, all things are objects, even class is a kind of object. If you want to copy a object, then the ID of these two objects are the same which means the two objects are are stored in the same place. If you modify one object, then another object are also modified.

1
2
3
4
5
6
7
8
9
10
11
12
13
 class sample:
def __init__(self, items = []):
self.items = items

def append(self, value):
self.items.append(value)

s1 = sample(items=['1'])
s2 = s1
s1.append('a')
s2.append('b')

print(s1.items, s2.items)

result:

1
(['1', 'a', 'b'], ['1', 'a', 'b'])

another example:

1
2
3
4
5
a = [1,2,3,4]
b = a
b[0] = 100
print(a)
print(b)

result:

1
2
[100,2,3,4]
[100,2,3,4]

Instead, you should use “deepcopy” to copy two objects

1
2
3
4
5
a = [1,2,3,4]
b = copy.deepcopy(a)
b[0] = 100
print(a)
print(b)

result:

1
2
[1,2,3,4]
[100,2,3,4]

itertools

If you are too lazy to write a infinite loop in an iterator but you still want to reset to loop when iteration finished, then you should use itertools:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import itertools

def inc():
a = [1,2,3,4,5]
cs = itertools.cycle(a)
for i in cs:
yield i
x = inc()

print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))
print(next(x))

result:

1
2
3
4
5
6
7
8
1
2
3
4
5
1
2
3

concurrent.futures

If you are too lazy to write a multi-thread to process all the elements in a list which may cost lots of time, then you should use a python build-in multi-thread tools:

1
2
3
4
5
6
7
import concurrent.futures
def print_num(num):
print(num)

a = range(5)
with concurrent.futures.ProcessPoolExecutor() as executor:
executor.map(load_and_resize, a)

result:

1
2
3
4
5
0
1
2
3
4

< Python > Some python tricks you may never use But you should know

https://zhengtq.github.io/2018/12/05/python-tricks-1/

Author

Billy

Posted on

2018-12-05

Updated on

2021-03-12

Licensed under

Comments