Python Tricks

python tricks,持续更新……

启动服务器

1
2
3
4
5
# python2
python -m SimpleHTTPServer 8001

# python3
python3 -m http.server 3000

*args**kwargs

介绍

*args是可变的positional arguments列表 **kwargs是可变的keyword arguments列表

*args必须位于**kwargs之前

如果说在函数定义的位置使用*args**kwargs是一个将参数pack的过程,那么在函数调用的时候就是一个将参数unpack的过程了

参考

https://kodango.com/variable-arguments-in-python

一行式

1
2
3
class A(object):
    def __init__(self, a, b, c, d, e, f):
        self.__dict__.update({k: v for k, v in locals().items() if k != 'self'})

参考

https://eastlakeside.gitbook.io/interpy-zh/onelines

Python的itertools模板

参考: http://wklken.me/posts/2013/08/20/python-extra-itertools.html https://blog.csdn.net/fuxuemingzhu/article/details/79869193

可以先看下 itertools.combinations(points, 3)

1
2
itertools.permutations()全排列
itertools.combinations()组合

经典题目: https://leetcode-cn.com/problems/ambiguous-coordinates/description/

Python中定义二维数组

引入

昨天做算法题目的时候遇到一个贼坑的Python语法问题,就跟我以前开始不知道Python里面的字符串不可更改一样。

下面直接来看一个例子吧:

1
2
3
4
#coding: utf-8
a = [[]]*5
a[0].append(1)
print a

对于上面这个例子,我心里的预期结果是:

1
[[1], [], [], [], []]

但是很遗憾我得到的结果却是:

1
[[1], [1], [1], [1], [1]]

为什么会这样呢?究其原因是因为Python的语法特性,直接来看官方文档的解释

What has happened is that [[]] is a one-element list containing an empty list, so all three elements of [[]] * 3 are references to this single empty list. Modifying any of the elements of lists modifies this single list.

所以创建二维数组时,应该按照以下方法创建:

1
2
3
4
5
6
>>> lists = [[] for i in range(3)]
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]

参考: https://www.cnblogs.com/woshare/p/5823303.html

延伸

新手常犯的错误:直接google新手常犯的错误

字典(dict)

基础使用

Python 中的动态数组是如何使用的 获取字典的键值和values

dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回default值 参考:菜鸟教程

按key值或按value值排序

下面是按key对字典进行排序

1
d = sorted(data.items(), key=lambda item:item[0], reverse=True)

一个有趣的python排序模块:bisect

参考:https://www.cnblogs.com/skydesign/archive/2011/09/02/2163592.html

python 中swap

1
2
3
4
a, b = b, a
b, a = a, b

在涉及到数组的时候会有点不一样有时候出错很可能会在这里出错最保险的是用3行进行交换

Python模块包

可以将功能相似的模块放在同一个文件夹(比如说this_dir)中,构成一个模块包。

通过

1
import this_dir.module

引入this_dir文件夹中的module模块。

该文件夹中必须包含一个__init__.py的文件,提醒Python,该文件夹为一个模块包。__init__.py可以是一个空文件。

Python排序

Python对二维数组进行排序

1
2
3
4
5
6
7
8
9
a = [[2,3],[1,2],[5,2],[4,1]]
# 按照第二列进行排序
b = sorted(a, key=lambda a:a[1])

a = [[3, 4], [5, 6], [6, 5], [7, 2], [7, 0], [7, 1]]
#如果第一个元素相同那么按照第二个元素排序
c = sorted(a, key=lambda a:(a[0],a[1]))
# 添加负号表示逆序
c = sorted(a, key=lambda a:(-a[0],a[1]))

参考: https://blog.csdn.net/hanshileiai/article/details/44241385

题目:406. 根据身高重建队列

yield用法

简介

next() send() yield from 的用法 参考: http://youchen.me/2017/02/10/Python-main-use-for-yield-from/ http://blog.gusibi.com/post/python-coroutine-yield-from/

参考: https://www.jianshu.com/p/d676543ccdbb https://zhuanlan.zhihu.com/p/23276711 http://pyzh.readthedocs.io/en/latest/the-python-yield-keyword-explained.html

python zip()

关于zip的使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution(object):
    def carFleet(self, target, position, speed):
        cars = sorted(zip(position, speed))
        times = [float(target - p) / s for p, s in cars]
        ans = 0
        while len(times) > 1:
            lead = times.pop()
            if lead < times[-1]: ans += 1  # if lead arrives sooner, it can't be caught
            else: times[-1] = lead # else, fleet arrives at later time 'lead'

        return ans + bool(times) # remaining car is fleet (if it exists)

例子: https://leetcode.com/problems/car-fleet/solution/

牛逼哄哄的注释

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#             Python大法好 入教保平安
#                    _ooOoo_
#                   o8888888o
#                   88" . "88
#                   (| °_° |)
#                   O\  =  /O
#                ____/`---'\____
#              .'  \\|     |//  `.
#             /  \\|||  :  |||//  \
#            /  _||||| -:- |||||-  \
#            |   | \\\  -  /// |   |
#            | \_|  ''\---/''  |   |
#            \  .-\__  `-`  ___/-. /
#          ___`. .'  /--.--\  `. . __
#       ."" '<  `.___\_<|>_/___.'  >'"".
#      | | :  `- `.;`\ _ /`;.`/ - ` : | |
#      \  \ `-.   \_ __\ /__ _/   .-` /  /
# ======`-.____`-.___\_____/___.-`____.-'======
#                    `=---='
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#             佛祖保佑       永无BUG
#    练手项目 锻炼技巧 不要做坏事 出事与本人无关

列出当前目录下所有文件和目录名

1
2
import os #导入os模块,模块的概念后面讲到
[d for d in os.listdir('.')] # os.listdir可以列出文件和目录

简易进度条

1
2
3
import sys
sys.stdout.write("#:{0}\r".format(i))
sys.stdout.flush() 

\r 回到一行的头部

example:

1
2
3
4
5
6
7
8
#encoding: utf-8
import sys
import time

for i in range(30):
	time.sleep(0.5)
	sys.stdout.write("##:{0}/30\r".format(i))
	sys.stdout.flush() 

参考: http://python.jobbole.com/83692/

collections

1
2
3
4
5
6
7
import collections
lst = []    # lst存放所谓的100万个元素
d = collections.Counter(lst)
# 瞬间出结果
for k in d:
    # k是lst中的每个元素
    # d[k]是k在lst中出现的次数

hostname->IP

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#Resolve all hostnames in a file to IP addresses:
import sys, socket
f = open(sys.argv[1])
for i in f:
    i = i.rstrip()
    try:
        ip = socket.gethostbyname(i)
    except:
        ip = "Doesn't resolve"
    print(i + " -> " + ip)

Py 文件转成 EXE 文件

参考:https://www.youtube.com/watch?v=UZX5kH72Yx4&t=28s

这里我使用这个项目作为示例:https://github.com/yangshun/2048-python

1
2
3
$pip3 install pyinstaller
# 这一步会生成两个文件夹和一个文件,只保留 dir 里面的 exe 文件就可以了
$pyinstaller --onefile -w puzzle.py

下面将生成的 exe 文件移动到项目的主目录下,然后生成 zip 文件

使用 NSIS 生成最终的可以在 windows 上安装的 exe 文件就可以了

单下划线和双下划线

单下划线

单下划线前缀名称(例如_pythonPoint): 这表示这是一个保护成员(属性或者方法),只有类对象和子类对象自己能访问到这些变量,是用来指定私有变量和方法的一种方式(约定而已)。

单下划线后缀名称: 通常用于和Python关键词区分开来

双下划线

“双下划线” 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

ref

https://zhuanlan.zhihu.com/p/36173202

https://juejin.im/post/6844903937976303624