0.
0.1 取反:
s=s[::-1]
s=inversed(s)
0.2 三目运算:
h = "变量1" if a>b else "变量2"
0.3 造数组
a1=[0]*8
a1=list(itertools.repeat(0,8))
a2=range(0,8)
a3=[[0]*3 for _ in range(0,5)] #5行3列0
a1=list(itertools.repeat([0]*3,5))
## 误区-浅拷贝
>>> mat=[[0]*3]*3
>>> mat
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> mat[0][0]=1
>>> mat
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
0.4 正负无穷大
python中并没有特殊的语法来表示这些值,但是可以通过 float()
来创建它们:
>>> a = float("inf")
>>> b = float("-inf")
>>> a
inf
>>> b
-inf
0.5 True的数字含义,1
>>> sum([True,False])
1
>>> sum([True,False,True])
2
>>> 0+True
1
>>> 2+True
3
0.6 按列取元素
>>> a=[[1,2,3], [4,5,6]]
>>> a[:, 0] # 尝试用数组的方法读取一列失败,这是numpy的用法
TypeError: list indices must be integers or slices, not tuple
>>> b = [i[0] for i in a] # 从a中的每一行取第一个元素。
>>> print(b)
[1, 4]
>>> a=[[1,2],[3,4],[5,6]]
>>> list(zip(*a))
[(1, 3, 5), (2, 4, 6)]
>>> list(zip(*a))[0]
(1, 3, 5)
# zip可同时zipN个可迭代对象,所以可以用*a来解包裹
>>> b=[[1,2,3],[4,5,6],[7,8,9]]
>>> list(zip(*b))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
>>> a=[1,2,3]
>>> b=[4,5,6]
>>> c=[7,8,9]
>>> list(zip(a,b,c))
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
0.7 多层循环生成器:
# grid=[[r1],[r2],...]
ans += sum(v > 0 for row in grid for v in row)
1.sum(), min(), max()等可接收iterable参数的,可直接用generator作为参数,可利用此特性减少内存开销。
由于min()和max()还可接收key函数,所以也可用key函数代替generator方式
s = sum((x * x for x in nums)) # 用生成器表达式
s = sum(x * x for x in nums) # 可更精简
portfolio = [
{'name':'GOOG', 'shares': 50},
{'name':'YHOO', 'shares': 75},
{'name':'AOL', 'shares': 20},
{'name':'SCOX', 'shares': 65}
]
# 原始--生成器: Returns 20
min_shares = min(s['shares'] for s in portfolio)
# 可代替: Returns {'name': 'AOL', 'shares': 20}
min_shares = min(portfolio, key=lambda s: s['shares'])
2.字符串连接用join 替代累加+=
因为每次+=都会创建新的字符串对象,效率低:
s = ''
for p in parts:
s += p
#不如
''.join(parts)
3.将要被用到的很多小字符串构造成生成器使用
def sample():
yield 'Is'
yield 'Chicago'
yield 'Not'
yield 'Chicago?'
text = ''.join(sample())
4.vars(),配合foramat_map使用、__missing__处理字典缺失值
#取local变量
>>> s = '{name} has {n} messages.'
>>> name = 'Guido'
>>> n = 37
>>> s.format_map(vars())
'Guido has 37 messages.'
#取对象属性
>>> class Info:
... def __init__(self, name, n):
... self.name = name
... self.n = n
...
>>> a = Info('Guido',37)
>>> s.format_map(vars(a))
'Guido has 37 messages.'
#避免没赋值报错
class safesub(dict):
def __missing__(self, key):
return '{' + key + '}'
>>> del n # Make sure n is undefined
>>> s.format_map(safesub(vars()))
'Guido has {n} messages.'
#构造实用函数
import sys
def sub(text):
return text.format_map(safesub(sys._getframe(1).f_locals))
>>> name = 'Guido'
>>> n = 37
>>> print(sub('Hello {name}'))
Hello Guido
>>> print(sub('You have {n} messages.'))
You have 37 messages.
>>> print(sub('Your favorite color is {color}'))
Your favorite color is {color}
注释:
sys.
_getframe
([depth]):https://docs.python.org/zh-cn/3/library/sys.html#module-sys
depth默认值为0。用于获取frame object(帧对象)情况
def get_cur_info():
print(sys._getframe().f_code.co_filename) # 当前文件名,可以通过__file__获得
print(sys._getframe(0).f_code.co_name) # 当前函数名
print(sys._getframe(1).f_code.co_name) # 调用该函数的函数名字,如果没有被调用,则返回<module>
print(sys._getframe(0).f_lineno) #当前函数的行号
print(sys._getframe(1).f_lineno) # 调用该函数的行号
print(sys._getframe(1).f_locals)# 调用该函数的本地变量字典
frame object(帧对象)
帧对象表示执行帧。它们可能出现在回溯对象中 (见下文),还会被传递给注册跟踪函数。
特殊的只读属性: f_back
为前一堆栈帧 (指向调用者),如是最底层堆栈帧则为 None
; f_code
为此帧中所执行的代码对象; f_locals
为用于查找本地变量的字典; f_globals
则用于查找全局变量; f_builtins
用于查找内置 (固有) 名称; f_lasti
给出精确指令 (这是代码对象的字节码字符串的一个索引)。
特殊的可写属性: f_trace
,如果不为 None
,则是在代码执行期间调用各类事件的函数 (由调试器使用)。通常每个新源码行会触发一个事件 - 这可以通过将 f_trace_lines
设为 False
来禁用。
具体的实现 可能 会通过将 f_trace_opcodes
设为 True
来允许按操作码请求事件。请注意如果跟踪函数引发的异常逃逸到被跟踪的函数中,这可能会导致未定义的解释器行为。
f_lineno
为帧的当前行号 --- 在这里写入从一个跟踪函数内部跳转的指定行 (仅用于最底层的帧)。调试器可以通过写入 f_lineno 实现一个 Jump 命令 (即设置下一语句)。
帧对象支持一个方法:
frame.
clear
()
此方法清除该帧持有的全部对本地变量的引用。而且如果该帧属于一个生成器,生成器会被完成。这有助于打破包含帧对象的循环引用 (例如当捕获一个异常并保存其回溯在之后使用)。
如果该帧当前正在执行则会引发 RuntimeError
。