1.用生成器表达式初始化元组
虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成器表达式是更好的选择。这是因为生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。前面那种方式显然能够节省内存。生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已。
from collections import Iterator,Iterable
g = [i**2 for i in range(5)]
print(f"g={g}")
h = (i**2 for i in range(5))
print(f"h={h}")
print(isinstance(g,Iterator))
print(isinstance(g,Iterable))
print(isinstance(h,Iterator))
print(isinstance(h,Iterable))
2. 使用生成器表达式计算笛卡儿积
colors=['white','black']
sizes=['M','S','L']
i=0
for tshirt in ('%s %s' % (c,s) for c in colors for s in sizes):
print(f"i={i},tshirt={tshirt}")
i+=1
3. 具名元组
collections.namedtuple是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类。这个带名字的类对调试有很大的帮助
from collections import namedtuple
City = namedtuple('City',['name','country','population','coordinates'])
tokyo = City('tokyo','NY',100,(10,20))
tokyo_name = tokyo.name
print(f"tokyo_name={tokyo_name}")
tokyo_1 = tokyo[1]
print(f"tokyo_1={tokyo_1}")
print(f"tokyo._fields={tokyo._fields}")
print(f"tokyo._asdict()={tokyo._asdict()}")
print(f"tokyo_before={tokyo}")
tokyo_after = tokyo._replace(name="update_tokyo")
print(f"tokyo_after={tokyo_after}")
print(f"tokyo={tokyo}")
tokyo_name=tokyo
tokyo_1=NY
tokyo._fields=('name', 'country', 'population', 'coordinates')
tokyo._asdict()=OrderedDict([('name', 'tokyo'), ('country', 'NY'), ('population', 100), ('coordinates', (10, 20))])
tokyo_before=City(name='tokyo', country='NY', population=100, coordinates=(10, 20))
tokyo_after=City(name='update_tokyo', country='NY', population=100, coordinates=(10, 20))
tokyo=City(name='tokyo', country='NY', population=100, coordinates=(10, 20))
4. sys.argv
sys.argv是获取运行python文件的时候命令行参数
- 我们通过命令行创建一个a.py文件
vim a.py
- 在文件中输入如下代码:
import sys
a = sys.argv
b = len(sys.argv)
a_1 = sys.argv[0]
a_2 = sys.argv[1]
a_3 = sys.argv[-1]
print(f"a={a}")
print(f"a_1={a_1}")
print(f"a_2={a_2}")
print(f"a_3={a_3}")
print(f"b={b}")
- 命令行输入如下命令来运行
a.py
python a.py hello my friends!
- 得到相关结果:
我们发现,sys.argv 将我们输入的命令进行分割后保存为列表形式后赋值给 a
a=['a.py', 'hello', 'my', 'friends!']
a_1=a.py
a_2=hello
a_3=friends!
b=4
5. bisect
5.1 bisect相关函数测试
import bisect
a = [1,4,6,8,15,17,18,20]
position = bisect.bisect(a,13)
print(f"position={position}")
print(f"a={a}")
a.insert(position,13)
print(f"a={a}")
b = [1,4,6,8,12,15,16,20]
print(f"b={b}")
bisect.insort(b,13)
print(f"b={b}")
position=4
a=[1, 4, 6, 8, 15, 17, 18, 20]
a=[1, 4, 6, 8, 13, 15, 17, 18, 20]
b=[1, 4, 6, 8, 12, 15, 16, 20]
b=[1, 4, 6, 8, 12, 13, 15, 16, 20]
5.2 bisect_left,bisect_right
- 如果列表中没有x,那么bisect_left(ls,x)和bisect_right(ls,x)返回相同的
位置值 ,该值是x在ls中合适的插入点索引,使得数组有序 ,保证 ls[index2] > x,ls[index3] > x
import bisect
ls = [1,5,9,13,17]
index1 = bisect.bisect(ls,7)
index2 = bisect.bisect_left(ls,7)
index3 = bisect.bisect_right(ls,7)
print("index1 = {}, index2 = {}, index3 = {}".format(index1, index2, index3))
- 如果列表中有x,那么就可以看出来bisect_left表示当前元素位置的左边,bisect_right表示当前元素位置的右边
import bisect
ls = [1,5,9,13,17]
index1 = bisect.bisect(ls,9)
index2 = bisect.bisect_left(ls,9)
index3 = bisect.bisect_right(ls,9)
print("index1 = {}, index2 = {}, index3 = {}".format(index1, index2, index3))
5.3 案例
import bisect
import sys
HAYSTACK = [1,2,4,5,6,8,12,15,20,21,23,23,26,29,30]
NEEDLES = [0,1,2,5,8,10,22,23,29,30,31]
ROW_FMT = '{0:2d} @ {1:2d} {2}{0:<2d}'
def demo(bisect_fn):
for needle in reversed(NEEDLES):
position = bisect_fn(HAYSTACK,needle)
offset = position * ' |'
print(ROW_FMT.format(needle,position,offset))
if __name__ == '__main__':
if sys.argv[-1]=='left':
bisect_fn=bisect.bisect_left
else:
bisect_fn=bisect.bisect
print('DEMO:',bisect_fn.__name__)
print('haystack->',' '.join('%2d' % n for n in HAYSTACK))
demo(bisect_fn)
/root/.local/share/jupyter/runtime/kernel-5632752f-4fed-413b-aa39-507d059d85d3.json
DEMO: bisect_right
haystack-> 1 2 4 5 6 8 12 15 20 21 23 23 26 29 30
31 @ 15 | | | | | | | | | | | | | | |31
30 @ 15 | | | | | | | | | | | | | | |30
29 @ 14 | | | | | | | | | | | | | |29
23 @ 12 | | | | | | | | | | | |23
22 @ 10 | | | | | | | | | |22
10 @ 6 | | | | | |10
8 @ 6 | | | | | |8
5 @ 4 | | | |5
2 @ 2 | |2
1 @ 1 |1
0 @ 0 0
|