前言
最近到了暑期实习的招聘期,看着小伙伴们准备各厂的面试,刷题刷算法刷数据结构,突然感觉自己好菜啊。一说红黑树,就记得数据结构讲过,到底是什么都忘得干干净净。至于算法本身也没有好好学习过,只懂得一些基本的递归的思路。(不过这学期有选算法课,希望能好好学哈哈哈)
虽然目前的定位不是就业,但是感觉迟早要去产业界的话多刷刷题还是没有缺点的,而且刷题的过程也蛮好玩的(主要原因)。于是注册了一个 LeetCode 账号。这里发现好像国区有专属的服务,国内想去国际版的 LeetCode 貌似还很麻烦,找了很多对比,最后还是进了国区。随便试试一道题,发现居然支持十多种语言,连最近在学的 Kotlin 都有(TIOBE 排行34 的语言也太有面子了)。然鹅具体要用什么语言的时候却开始选择困难了,因为自己学语言基本都是入了门就没往深学了,都是半吊子,刷 LeetCode 的话还是希望能够让自己有一门非常熟悉的语言。Java 常年最流行语言,产业界常青藤,开发后盾、开发App、乃至web都会用到; Python 这些年也十分火热,写的方便,还有近些年大火的机器学习;作为安全专业科班出身,C、C++十分差劲也说不过去;尤其科研上准备往浏览器和 Web 方向前进, JavaScript, PHP 也要加深掌握。然后头秃了。最后思前想后还是打算做了 Python,毕竟现在 Python 和机器学习数据分析的需求量还是相当猛的(参考最近看到的各类招聘)。于是就有了这一篇博文。然后又惊喜的发现,最近刷的很舒服的 JetBrains Academy 有 python 的课程。于是打算先把 Kotlin 的这个项目刷完就去做 Python,然后尽可能坚持用 Python 刷 LeetCode。
参考资料
- www.Python.org
- https://leetcode-cn.com/
- https://hyperskill.org/curriculum JetBrains Acedemy 的官网
- https://www.python.org/dev/peps/pep-0008/ PEP 8 代码规范
- https://www.python.org/dev/peps/pep-0020/ The Zen of Python
- https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html Pycharm官方快捷键指南
- https://blog.csdn.net/qq_35290785/article/details/90634344 python中 r’’, b’’, u’’, f’’ 的含义
正文
PEP 8
PEP 即 Python Enhancement Proposal。
一行不要超过 79 个字符。当然没人会记忆和数的,大部分编辑器或者 IDE 都有类似功能。
避免不必要的空格。
- Avoid extra spaces within parentheses.
Good:
1 print('Hello!')Bad:
1 print( 'Hello!' )
- Avoid an extra space before an open parenthesis.
Good:
1 print('some text')Bad:
1 print ('some text')
关于双引号,因为 Python 不区分字符和字符串,单引号双引号可以互换,所以尽可能避免用转义来打出引号。比如有单引号的字符串就用双引号括起来,有双引号的字符串就用单引号括起来。
命名变量
使用小写字母和下划线命名。使用ASCII编码(尤其不要用一些其他类似西里尔文字的字母混淆)。不要用 l 和 1,o 和 O 和 0 等容易混淆的字符。如果最合适的变量名被Python关键字占了,在后面加个下划线。
1 | class_ = type(var) # yes |
注释
注释可以用 # ,这适用于大多数情况,在使用时,确保 # 前有2个空格,以及后面有1个空格。
1 | print("Learning Python is fun!") # This is a proper comment formatting |
多行时请分开使用 # 。 """..."""
也可以达到多行注释的效果。但是在一般情况下请不要使用这个,因为在官方推荐中,三个双引号用于 documentation strings 或者叫 docstrings ,仅用于函数、方法和其他极少数情况。
1 | # Imagine that this is an example of a really long comment |
如果可以通过优化代码减少注释,那就 do it.
1 | n = 0 # number of participants # wrong |
例如上面的代码,不要用第一行的写法。
另外不要写显而易见的注释。
通常,注释应该解决的是 why 而不是 what。去解释为什么编写这样的代码,而不是说明做了什么。
遍历 Dict
下面给出遍历 Dict 的 3 种方式。首先是遍历 key,直接使用 for in 会遍历 keys。
1 | # Python3 code to iterate through all keys in a dictionary |
第二种使用 values() 方法,遍历 Value。
1 | # Python3 code to iterate through all values in a dictionary |
最后一种使用 items() 方法同时遍历 key 和 value。
1 | # Python3 code to iterate through all key, value |
List comprehension
终于遇到了一个自己不熟的知识点!刷 hyperSkill 刷的前期感觉都是基础知识,哈哈哈终于刷到了一个感觉扩展知识面的知识点。
List comprehension 能够利用任意 iterable 的对象生成列表,语法如下。
1 | # list comprehension syntax |
该语法不只是复制列表用的,可以在过程中做一些额外操作。
1 | # squared numbers |
此外还可以用 if 筛选元素。
1 | # list comprehension with condition |
接下来是超级硬核的嵌套 List Comprehension。不过不建议使用这种方式,因为可读性会下降,而且读起来很反直觉。
1 | # original list |
Scope
LEGB 法则:
Python 中的变量遵循 LEGB rule. 这意味着解释器按照下面的顺序寻找变量。:
- Locals. 函数体内未声明 global 的变量.
- Enclosing. 从里到外嵌套的函数的 Locals.
- Globals. 在模块最顶层定义的变量或者 声明了 global 的变量.
- Built-in. Python 内建变量。
在对 global
变量进行修改前必须在函数内使用 global 声明。
nonlocal
可以使得我们可以对外界的变量赋值(不是 global
的)
global
和 nonlocal
都不是很常用,因为这样会使得程序难以阅读。
Any and All
两个函数都只能对 iterable 的对象使用。如果传入的对象不是 bool 类,结果参考 bool() 函数,比如 1 会被当做 True, 0 会被当做 False。
Any 当输入中的元素中存在 True 时 返回 True。传入空对象时,返回 False。
All 当输入中的元素中全为True 时 返回 True。传入空对象时,返回 True。
1 | rocket_science_scores = [0, -0, 0.0, +0] |
字符串操作
startswith()
startswith() 函数可以判断一个字符串是否在另一个字符串的开头。
参考资料 : https://www.runoob.com/python/att-string-startswith.html
简单用法:
1 | str = "this is string example....wow!!!"; |
格式化字符串
参考资料: https://docs.python.org/3.6/library/string.html#format-specification-mini-language
最基本的 string % value 是模仿了C语言的语法。
首先是 str. format() 方法。
1 | print('Mix {}, {} and a {} to make an ideal omelet.'.format('2 eggs', '30 g of milk', 'pinch of salt')) |
然后是 Formatted string literals ,又叫 f-strings 。
1 | name = 'Elizabeth II' |
命令行参数
你可以在命令行中使用类似下面的命令运行python脚本。后面由空格分隔的部分是参数。
1 | python C:\python_scripts\add_two_numbers.py 11 44 |
使用 sys 模块来获取命令行参数。
1 | import sys # first, we import the module |
sys.argv[0]
是脚本的名字,具体是相对路径还是绝对路径取决于你是怎么输入命令行的命令的,和你命令行输入的路径一致。另外记住传入的参数类型均为 字符串。
Context Manager : With as
Context Manager 这个名字一听属实有点唬人,了解一下就发现是之前经常见到的 with ... as
语句。
这种语法的引入背景是当用户开启过多的文件时,会报错,而很多时候用户忘记或者不知道何时关闭文件,使用 Context Manager 可以高效的管理,并且避免文件开启过多带来的各种问题。
基本语法如下:
1 | # invoking a context manager |
statement 需要支持 context manager 的操作,这里列举一些常用的 context manager:
- File objects (and other streams like
io.StringIO
orio.BytesIO
);
- Sockets;
- Locks and semaphores in the
threading
module; - Database connections;
- Mock objects.
不过绝大多数时候,我们都是在于文件交互时使用这个语法。
使用这种语法就可以不用在调用 f.close() 了,但是你也可以调用但是并不建议这样做。
使用样例:
1 | with open('tarantino.txt', 'r', encoding='utf-8') as f: |
另外还可以同时打开多个文件:
1 | with open('tarantino.txt', 'r', encoding='utf-8') as in_file, \ |
Set
set 中存储独立元素,正如数学中的 set (集合)。
set 中添加元素 使用 add 方法,删除元素使用 remove 方法或者 discard 方法,唯一区别在于 remove 方法在没有对应元素时会报错 Key Error。
1 | nums = {1, 2, 2, 3} |
另外一个有意思的是 pop 方法,由于 set 中元素是无序的,pop 方法会删除并返回一个随机元素。
update 方法可以把传入的参数内的每一个元素都 add 进 set。
Python 字符串中的 f
最初看到了一个奇怪的语法:print(f’My name is {name}’)
好奇里面的 f 是什么,毕竟 b 什么的很常见, f 第一次见。搜了一下就是把大括号里的字符串当变量输出。太方便了!之前一直憨憨的用字符串拼接和str()。
1 | import time |
杂项
多行字符串使用 三引号。
1 | print("""This |
Python 的 for … else 语法:在 python 中,for … else 表示这样的意思,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。
1 | for num in range(10,20): # 迭代 10 到 20 之间的数字 |
可以用 maxsplit
参数来指定split 函数能split 几次,最后返回的 list 的元素个数会是 maxsplit + 1
.
1 | # maxsplit example |
使用 Named Argument 时,需要注意,Named Argument 需要放到最后面。
1 | greet("Frodo", surname="Baggins") # Hello, Frodo Baggins |
parameters 是形参,arguments 是实参。
Python 字符串排序时,是先按第一位按字母序排序,然后第二位、第三位等等。举个栗子。
1 | >>> a = ['a','b','c','ab','ac','ba','bc','ca','cb','abc','acb'] |