*
的坑board = [['_'] * 3 for i in range(3)]
board
Out[46]:
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
In [47]:
board
board[1][2] = 'X'
board
Out[47]:
[['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]
这个相当于
board = []
for i in range(3):
row = ['_'] * 3
board.append(row)
board
Out[57]:
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
In [58]:
board[1][2] = 'X'
board
Out[58]:
[['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]
但是
weird_board = [['_'] * 3] * 3
weird_board
weird_board = [['_'] * 3] * 3
weird_board
Out[59]:
[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
In [60]:
weird_board[1][2] = 'X'
weird_board
Out[60]:
[['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']]
相当于
row = ['_'] * 3
weird_board = []
for i in range(3):
weird_board.append(row)
weird_board[1][2] = 'X'
weird_board
Out[62]:
[['_', '_', 'X'], ['_', '_', 'X'], ['_', '_', 'X']]
+=
要注意的 首先 a+=b
会调用a实现了的 __iadd__
方法, 如果没有这个方法才会调用 __add__
方法。而可变序列一般都实现了 __iadd__
方法, 而不可变对象根本不支持这个操作。下面展示了 *=
再不可变序列上的作用。l = [1,2,3]
In [1]: l=[1,2,3]
In [2]: id(l)
Out[2]: 2396048446664
In [3]: l *= 2
In [4]: l
Out[4]: [1, 2, 3, 1, 2, 3]
In [5]: id(l)
Out[5]: 2396048446664
In [6]: t=(1,2,3)
In [7]: id(t)
Out[7]: 2396048383360
In [8]: t*=2
In [9]: t
Out[9]: (1, 2, 3, 1, 2, 3)
In [10]: id(t)
Out[10]: 2396048501448
出现这样的原因就是因为list的l调用了list里的 __iadd()__
方法,而属于tuple的t由于不支持修改没有 __iadd()__
方法而调用了 __add()__
方法。
In [13]: t = (1, 2, [30, 40])
In [14]: t[2] += [50,60]
以上代码的输出是什么?
答案是什么?你以为是b,其实是d,a和b都是对的。结果是
In [13]: t = (1, 2, [30, 40])
In [14]: t[2] += [50,60]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-14-fb586dd7f384> in <module>()
----> 1 t[2] += [50,60]
TypeError: 'tuple' object does not support item assignment
In [15]: t
Out[15]: (1, 2, [30, 40, 50, 60])
原因是+=不是原子操作,尽量不要再tuple里嵌套可变对象。可以查看字节码来真相了
In [11]: from dis import dis
In [12]: dis('s[a] += b')
1 0 LOAD_NAME 0 (s)
2 LOAD_NAME 1 (a)
4 DUP_TOP_TWO
6 BINARY_SUBSCR # 将s[a]的值压入栈顶TOS(Top of Stack)
8 LOAD_NAME 2 (b)
10 INPLACE_ADD # 计算TOS += b 这里能完成是因为TOS指向的是一个可变对象。
12 ROT_THREE
14 STORE_SUBSCR # 这一步失败,因为s是不可变元组
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
bisect.bisect(haystack,needle)
haystack是干草垛的意思,needle是针的意思。会用二分查找法返回needle在haystack中之后的位置。 bisect.bisect_left(haystack,needle)
返回的是needle在haystack中之前的位置。 bisect.insort(seq,item)
可以插入元素。bisect.bisect举例:
import bisect
def grade(score):
breakpoints = [60, 70, 80, 90]
grades = 'EDCBA'
i = bisect.bisect(breakpoints, score)
return grades[i]
print([grade(score) for score in [33, 99, 77, 70, 89, 90, 100]])
[Out] ['E', 'A', 'C', 'C', 'B', 'A', 'A']
bisect.insort举例:
import bisect
import random
SIZE = 7
random.seed(1729)
my_list = []
for i in range(SIZE):
new_item = random.randrange(SIZE * 2)
bisect.insort(my_list, new_item)
print('%2d ->' % new_item, my_list)
[Out]
10 -> [10]
0 -> [0, 10]
6 -> [0, 6, 10]
8 -> [0, 6, 8, 10]
7 -> [0, 6, 7, 8, 10]
2 -> [0, 2, 6, 7, 8, 10]
10 -> [0, 2, 6, 7, 8, 10, 10]
from array import array
from random import random
floats = array('d', (random() for i in range(10 ** 7)))
print(floats[-1])
fp = open('floats.bin', 'wb')
floats.tofile(fp)
fp.close()
floats2 = array('d')
fp = open('floats.bin', 'rb')
floats2.fromfile(fp, 10 ** 7)
fp.close()
print(floats2[-1])
print(floats2 == floats)
[Out]
0.48178023314354956
0.48178023314354956
True
使用array.tofile和array.fromfile要比直接读取float对象要快很多。
memoryview.cast()
会把同一块内存的内容打包成一个全新的memoryview对象给你。from array import array
numbers = array('h', [-2, -1, 0, 1, 2])
memv = memoryview(numbers)
print(len(memv))
print(memv[0])
memv_dict = memv.cast('B')
print(memv_dict.tolist())
memv_dict[5] = 4
print(numbers)
[Out]
5
-2
[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]
array('h', [-2, -1, 1024, 1, 2])
h是2个字节的有符号整型,B是1个字节无符号整型。因为我们把占两个字节的整数的高位变成了4,所以这个有符号整数的值就变成了1024. 1.numpy是优秀的库,实现了多维同质数组。代码举例
import numpy
a = numpy.arange(12)
print(a)
# [ 0 1 2 3 4 5 6 7 8 9 10 11]
print(type(a)) # <class 'numpy.ndarray'>
print(a.shape) # 结果是一个一维数组,元素有12个
a.shape = 3, 4 # 把数组变成二维的
print(a)
# [[ 0 1 2 3]
# [ 4 5 6 7]
# [ 8 9 10 11]]
print(a[2]) # 打印第2行
# [ 8 9 10 11]
print(a[2, 1]) # 打印第2行第1列
# 9
print(a[:, 1]) # 打印第1列
# [1 5 9]
print(a.transpose()) # 行列交换
# [[ 0 4 8]
# [ 1 5 9]
# [ 2 6 10]
# [ 3 7 11]]