Python 基础语法 Pythonic 部分的总结
文章目录
一些废话
最近写 Python 代码时发现自己的代码很长,一个小模块也弄出了 200+ 行,而且代码多了,Debug 速度也很慢,开始怀疑自己会不会写 Py,所以想复习一下 Python 语法,这里总结一下自己看到的 Pythonic 的部分的语法。
赋值
Python 赋值是引用赋值。所以在函数传参时,改变实参的值,函数外传递的变量也会跟着改变。
对象的属性和方法都可以直接访问
除了可以使用成员访问符直接访问对象的属性和方法,也可以通过 getattr
方法和 setattr
方法直接访问对象的属性,这种通过名字访问对象属性的方式也叫做 ”反射“
检查两个引用是否指向同一个对象 —— is
关键字
可变对象与不可变对象
Python 中的大部分对象都是可变对象,即对象中包含的元素和值是可以被修改的,如列表、字典和用户自定义的对象。其他一些对象,如字符串和元组,是不可变对象。
常见的标量类型
类型 | 描述 |
---|---|
None | Python 中 “null” 值(只存在一个实例) |
str | 字符串类型,包含 Unicode (UTF-8 编码) 字符串 |
bytes | 原生 ASCII 字节(或者 Unicode 编码字节) |
float | 双精度 64 位浮点数值(并没有独立的 double 类型) |
bool | True 或 False |
int | 任意精度无符号整数 |
-
字符串格式化方式: str.format() 方法
原型:S.format(*args, **kwargs) -> str
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}" field_name ::= arg_name ("." attribute_name | "[" element_index "]")* arg_name ::= [identifier | digit+] attribute_name ::= identifier element_index ::= digit+ | index_string index_string ::= <any source character except "]"> + conversion ::= "r" | "s" | "a" format_spec ::= <described in the next section>
range 函数
range 函数返回一个迭代器,该迭代器生成一个等差整数序列
三元表达式
value = true-expr if condition else false-expr
与以下代码效果一致:
if condition:
value = true-expr
else:
value = true-expr
list 列表
-
list 添加元素有 append 方法和 insert 方法,insert 方法计算代价更高。如果想要在序列的头部和尾部都插入元素,那可以考虑
collections.deque
扫描二维码关注公众号,回复: 5958255 查看本文章 -
insert 方法的反操作是 pop,元素可以通过 remove 方法移除,该方法会定位第一个符合要求的值并移除它
-
使用
in
关键字可以检查一个值是否在列表中,但该过程是线性逐个扫描的,所以十分缓慢。而字典和集合中是基于哈希表的,所以二者该过程会很快 -
二分搜索和已排序列表的维护
内建的 bisect 模块实现了二分搜索和已排序列表的插值。
bisect.bisect
会找到元素应当被插入的位置,并保持序列排序,而bisect.insort
将元素插入到相应位置 -
切片:列表的切片操作为 seq[start:stop],其中区间为
[start:stop)
的左闭右开区间seq[::s]
意思是每隔 s 个取一个数值seq[::-1]
向步进传值 -1 可以对列表或者元组进行翻转 -
enumerate 内建函数作用于一个可迭代对象时,返回 (i, value) 元组序列,可以实现在遍历一个序列的同时追踪当前元素的索引
原型: enumerate(iterable[, start]) -> iterator for index, value of iterable
例子:
strings = ["foo", "card", "bar", "aaaaaa", "abababa"] for index, value in enumerate(strings): print("index: {0} value: {1}".format(index, value)) # 输出 # index: 0 value: foo # index: 1 value: card # index: 2 value: bar # index: 3 value: aaaaaa # index: 4 value: abababa
dict 字典
-
从字典中删除关键字可以用
del
方法,pop
方法会在删除的同时返回被删除的值 -
keys 方法和 values 方法分别返回提供字典键、值的迭代器
-
update 可以将两个字典合并
-
从序列中生成字典有两种方式:
-
最容易想到也是比较低效的写法是
mapping = {} for key, value in zip(key_list, value_list): mapping[key] = value
-
一种高效的写法是
mapping = dict(zip(range(5), reversed(range(5))))
-
另一种高效的写法是字典生成式
-
-
默认值
-
字典的 get 方法和 pop 方法可以返回一个默认值:
if key in some_dict: value = some_dict[key] else: value = default_value # 上面代码的一种高效实现如下 value = some_dict.get(key, default_value)
-
类似的,字典的赋值也有相应的方法
words = list(some_value, ...) by_letter = {} for word in words: letter = word[0] if letter not in by_letter: by_letter[letter] = [word] else: by_letter[letter].append(word) # 上面代码的一种高效实现如下 for word in words: letter = word[0] by_letter[letter].setdefault(letter, []).append(word) # 利用内建的集合模块 defaultdict 也可实现相同的功能 from collections import defaultdict by_letter = defaultdict(list) for word in words: by_letter[word[0]].append(word)
-
列表、字典、集合的推导式
-
列表推导式允许过滤一个容器的元素,用一种简明的表达式转换传递给过滤器的元素,从而生成一个新的列表。
# 列表生成式写法 [expr for val in collection if condition] # 等价的 for 循环写法 result = [] for val in collection: if condition: result.append(expr)
-
字典的推导式
dict_comp = {key-expr : value-expr for value in collection if condition}
-
集合推导式
set_comp = {expr for value in collection if condition}
-
嵌套列表推导式:可以用来做容器的扁平化
flattened = [x for tup in some_tuples for some_tuples in some_lists if condition]
Map、Reduce、Filter
参考链接: Map, Filter and Reduce
-
Map: 对序列中的元素一次执行 function(item)
原型: map(func, *iterables) --> map object
例子:
def f(x): return x ** 2 data = [1, 2, 3, 4, 5, 6, 7, 8, 9] result = map(f, data) result # 输出: <map at 0x7fdb80523470> list(result) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81]
-
Reduce: 对序列上的元素迭代计算,直到序列减少到一个值,返回最终的结果。
原型: reduce(function, sequence[, initial])
例子:
from functools import reduce product = reduce((lambda x, y: x * y), [1, 2, 3, 4]) product # 输出: 24
-
Filter: 将过滤条件作用在序列上,并返回序列中满足条件的元素的迭代器。
原型:filter(function or None, iterable) --> filter object
例子:
filter_res = filter(lambda x: x<0, range(-5, 5)) filter_res # 结果: <filter at 0x7fdb80562dd8> list(filter_res) # 结果: [-5, -4, -3, -2, -1]
函数
-
函数的参数分为位置参数和关键字参数,关键字参数通常用于指定默认值或可选参数
例:
def func1(x, y, z=0.1): ... # 其中 x,y 为位置参数,z 为关键字参数
-
函数内部如果要使用函数外的全局变量, 应该在函数内用
global
关键字声明该全局变量 -
函数都是对象,充分利用这一特点可简化代码
例子: 对于字符串的清理工作,需要清理字符串中一些脏的空格、符号等
states = [" Alalama", " Geob", "BaBaBa*", "West vir? "] import re def clean_string(strings): result = [] for value in strings: value = value.strip() value = re.sub("[!#*?]", "", value) value = value.title() result.append(value) return result clean_string(states) # 结果: ['Alalama', 'Geob', 'Bababa', 'West Vir']
如果将该过程看作是将特定的操作应用到某个字符串的集合上,可以得到更高层面的写法,如下:
states = [" Alalama", " Geob", "BaBaBa*", "West vir? "] def remove_punctuation(value): return re.sub("[!*#?]", "", value) clean_ops = [str.strip, remove_punctuation, str.title] def clean_strings_op(strings, ops): result = [] for value in strings: for function in ops: value = function(value) result.append(value) return result clean_strings_op(states, clean_ops) # 结果: ['Alalama', 'Geob', 'Bababa', 'West Vir']
当然,等效的基于 Map-Reduce 的写法如下:
for x in map(str.title, map(str.strip, map(remove_punctuation, states))): print(x)
-
返回多个值,函数需要返回多个值时,直接 return 要返回的多个对象即可
def f(): some defination expression... return a, b, c
-
匿名函数,也称作 Lambda 函数,使用关键字 Lambda 定义
例子: 对字符串按照字符串中不同的字母数排序
strings = ["foo", "card", "bar", "aaaaaa", "abababa"] strings.sort(key=lambda x: len(set(list(x)))) strings # 结果 : ['aaaaaa', 'foo', 'abababa', 'bar', 'card']
生成器
- 迭代器是一种用于在上下文中(如 for 循环)向 Python 解释器生成对象的对象。
- 普通的函数执行并一次返回单个结果,而生成器则“惰性”地返回一个多结果序列,在每一个元素产生之后暂停,直到下一个请求。
- 如需创建一个生成器,只需在函数中将返回关键字 return 替换为 yeild 关键
-生成器的表达式和列表、字典、集合的推导式很类似,创建一个生成器表达式,只需将列表推导式中的中括号替换为小括号即可