*)python中没有Null,None不等同Null ,not检查的不是Null,not是非的意思
结论:if mark mark取值为None或者’‘ 都会是条件不成立
mark=None if mark: #print('None 和Null不等同,not 检查的是Null')#python中没有Null print('这时条件为真') else: print('结束') #结果: 结束 mark='' #结果: 结束 mark='1' #结果 这时条件为真
*)and运算符的一些疑惑
def not_empty(s): return s and s.strip()#我开始觉得可以直接返回s.strip(),后来发现这样不能处理None,然后我不知道这个s and s.strip()是什么意思 list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])) # 结果: ['A', 'B', 'C'] #如果其中有None、或者空’‘ 就返回None或者’‘ >>> None and '' >>> None and ' a' >>> '' and 'a' '' #其他就返回后面的那个 >>> 'a' and 'b' 'b' >>> 'b' and 'a' 'a' >>>
*)使用_接受函数返回值
def test1(): return 1,2 a,_=test1()#这个_不是python的关键字,而是自己起的变量名,不过形成了一种共识就是可以用它来代表无用的返回值 print(a,_)
#输出
1,2
#若是不加这个_的话
因为函数返回的是一个tuble,而当函数返回的是一个tuble的时候,可以省略括号,而多个变量可以同时接受一个tuble,按位置赋给对应的值
*)这样不会造成死循环
for i in range(10): i=1 print(i) #输出是10个1 #这样也不会 for i in range(10): while i<10: i+=1 print(i) print('*'*20,i)
*)奇怪,命名对他做了简化,为什么执行效率变低了呢?
#未简化的 def radix_sort(collection): ''' 自己写的1th 1000pic 0.0027,大步骤的原理见上''' # bucket=[[] for i in range(10)]#重复使用的变量应该清空 completed_negative=[]#负数 completed_plus=[] divisor=[pow(10,i) for i in range(10)]#这个应该够了,如果超出了就用divisor[-1]*10 for i in divisor: bucket=[[] for i in range(10)] if len(collection)==0:#都完成时退出,改为了0,因为不知道最后一个是正还是负 #completed.extend(collection) break for j in range(len(collection)): if collection[j]//i>0:#这样切割数据 bucket[(collection[j]//i)%10].append(collection[j])#考虑余数,直接将余数当成下标 #否则就说明已经完成了 elif collection[j]//i==0: # completed.append(collection.pop(j))#这里pop后会导致下标减少,以后会有溢出的危险可以使用修饰器解决? #要不先存起来,等会remove #也可以这里只设置一个标识,代表已经完成的数据的个数 completed_plus.append(collection[j]) elif collection[j]//i<-1:#位数还有 # bucket[10-(collection[j]//i)%10].append(collection[j])#这样是按照正数的方式放进去的,话句话说,就是按负数的绝对值放进去的, #而对于负数,绝对值越大,说明其值越小 # bucket[(10-(collection[j]//i)%10)%10].append(collection[j])#最后又%10是避免出现10-(20%10)=10的情况 bucket[(10-math.ceil(collection[j]/i)%10)%10].append(collection[j]) elif collection[j]//i==-1: if collection[j]/i==-1: bucket[(10-math.ceil(collection[j]/i)%10)%10].append(collection[j]) continue completed_negative.insert(0,collection[j])#这也是按照正数的方法来的,但对于负数来说,位数越少,其值越大 #所以最先结束的是最大的,就每次添加到列表的首元素 #之后再把数据按0-9的顺序从桶中取出来 collection=[]#其实前面不用删除, for k in bucket: if k: collection.extend(k) return completed_negative+completed_plus #简化的 def radix_sort(collection): result_negative=[] result_positive=[] divisor=1 while len(collection)>0: bucket=[[] for _ in range(10)] for j in range(len(collection)): if collection[j]//divisor>0: bucket[(collection[j]//divisor)%10].append(collection[j]) elif collection[j]//divisor==0: result_positive.append(collection[j]) continue elif collection[j]//divisor<-1: bucket[(10-math.ceil(collection[j]/divisor)%10)%10].append(collection[j]) elif collection[j]//divisor==-1: if math.ceil(collection[j]/divisor)==-1: bucket[(10-math.ceil(collection[j]/divisor)%10)%10].append(collection[j]) continue result_negative.insert(0,collection[j]) collection=[] divisor*=10 for k in bucket: if k: collection.extend(k) return result_negative+result_positive
*)return 可当作函数的退出语句
def test(a,*b): if a>5: return print(a) print(b) if __name__=="__main__": test(1,2,3) test(6,2,3) #输出 1 (2,3) 等于说第二次调用时在if后使用return退出了
*)raise后面的代码不会运行(unreachable code)
result=[1,2,3,69,8]#会使check_order 返回False if not check_order(result): raise Exception('排序失败!,测试已结束。collection:%s-----result:%s'%(collection,result)) print('raise 后面的代码不会运行,就像return 后面的代码') # flage=False # break #输出 (sort) λ 排序失败!,测试已结束。collection:[-353, -336, 282, 184, 346, -264, 375, 223, -611, 997]-----result:[1, 2, 3, 69, 8]
*)接受返回值,个数不符会出错(返回两个空估计可以了,不过这样没意义,不如在把下面的length==0的检查放到调用处)
if length<=1: if length==1: frames.append(render_area(all_collection,range_left_index,range_right_index,0,0,0,0)) return collection,frames#之前这里的位置写反过,导致输出的collection 是部分 else: return #或者: if length<=1: if length==1: frames.append(render_area(all_collection,range_left_index,range_right_index,0,0,0,0)) return collection,frames#之前这里的位置写反过,导致输出的collection 是部分 #接受返回值 collection,frames=func_call_above
*)这样会进入死循环
f __name__=='__main__': a=list(range(10)) while True: if not a: for node in a: a.remove(node)
*)在插入排序中,可以从后向前寻找位置,并且寻找的过程中可以一并让应该移动的元素移动,不过,是在移动的过程中,是让前后两个位置交换呢,还是等找好位置后再移动过去呢,实验表明,前者更省时间,可能跟复杂的判断有关系
#第二种方法:
for element_index in range(k-gap,index_of_gap-gap,-gap):#直接从这个元素前面的一个比较,记得将他是最小的两种单独考虑 if collection[element_index]>temp: collection[element_index+gap]=collection[element_index]#将这个放在上面, # collection[element_index]=temp if element_index==index_of_gap:#最小的就是如果到头还没有,因为是再遇见比他小的时候才赋值的,所以如果没有遇见最小的就要放到队头 collection[element_index]=temp else: collection[element_index+gap]=temp break
1000次平均时间0.00522711992
#第一种方法
for element_index in range(k-gap,index_of_gap-gap,-gap):#直接从这个元素前面的一个比较,记得将他是最小的两种单独考虑 if collection[element_index]>temp: collection[element_index+gap]=collection[element_index]#将这个放在上面, collection[element_index]=temp else: break
1000次平均时间0.00471744537
*)可以通过列表来为多个元素赋值,但赋值的个数必须和列表的长度相等
>>> a=[3,4] >>> b 5 >>> c Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'c' is not defined >>> b,c=a >>> b 3 >>> c 4 >>> a=[4,5,6] >>> b,c=a Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack (expected 2) >>>
*)Python中交换的快捷方式可以这样写:
a,b=b,a #下面这样写也是可以的 a,a=a,a
*)定义方法时参数名可以和其他的变量名相同,如果你能分得清的话,不会有任何影响
*)列表在普通赋值的时候随着一个改变,另一个列表的反应
测试一
>>> a=[1,2,3] >>> b=a >>> b [1, 2, 3] >>> a.pop() #对a进行一些内置方法的结果也会在b上体现出来 3 >>> a [1, 2] >>> b [1, 2] >>> a=[3,4] #但是通过赋值来修改a并不会在b上体现出来 >>> a [3, 4] >>> b [1, 2] >>>
一些略显沙雕的想法:b的任何改变都不会在a上体现出来。另外在把列表当成参数传进方法里,在方法里通过pop()等内置的方法对a进行操作时,也会在a上体现出来吗?会的
a=[2,3,4] b=[7,8,9] def test(collection): collection.pop() return collection#不管这里返回不返回都会体现出来 test(a) print(a) >>>[2,3]
测试2:
def test(list1,list2): '''测试列表复制后元数据的改变''' list3=list2 list3=list(map(lambda x:x+1,list2)) list3.append(5) list3.pop(0) print(list1+list2) if __name__=="__main__": list_test=[1] test(list_test,list_test) #输出 [1,1]
#测试3,无论多少次,只要是用赋值去赋值的,都回设计到所有版本的改变,但切片是例外的,切片得到的不是副本,而是一个新的
2 >>> a [2, 3, [[4], [5]]] >>> b=a >>> c=a >>> b[0]=5 >>> b [5, 3, [[4], [5]]] >>> c [5, 3, [[4], [5]]] >>> a [5, 3, [[4], [5]]] >>> d=b >>> d[0]=8 >>> d [8, 3, [[4], [5]]] >>> b [8, 3, [[4], [5]]] >>> a [8, 3, [[4], [5]]] >>> c [8, 3, [[4], [5]]] >>> >>> >>> #另一种复制,切片后复制 ... a=[1,2,3] >>> b=a >>> c=a >>> b=a[:2] >>> c=a[:2] >>> b[0]=7 >>> b [7, 2] >>> a [1, 2, 3] >>>
*)语法糖 不能 有break、return等语句
j-=1 if j>0 else return collection File "some_sort.py", line 98 j-=1 if j>0 else: return collection ^ SyntaxError: invalid syntax j-=1 if j>0 else return collection File "forTest.py", line 18 else break ^ SyntaxError: invalid syntax
*)无法使用一个break同时跳出两个for循环,但下面的可以
if __name__=='__main__': a=[2,3,4] b=[7,8,9] for i in a: for j in b: if j<10: flage=False break print("b") if not flage: break print("a")
*)在使用vs调试.py时候,同时用命令行也能运行,py虽然能在运行中更改,甚至能保存,但在本次调试的过程中修改不起作用
*)Windows的文件名不区分大小写
*)再对数组中元素重复访问时,想比较一下 每次都直接使用下标访问与先把数据取到变量里,然后每次都用变量 这两个的时间区别
结论:没有区别
#产生排序数组 startTime=time.time() collection=random.sample(range(-1000,1000),1000) endTime=time.time() print("耗费时间:",endTime-startTime) # collection =[-6,-5,-4,-8,7,9,3,1,2,233,45,634] # collection= [94, 37, 97, 31, 26, 79, 10, 35, 40, 6] # collection=[1,2,3,4,5,6,7,8,9] select_index=random.randint(0,99) startTime=time.time() for i in range(100000): print(collection[select_index],end='') # print("未排序之前:"+' '*68,collection)#不能写成+(会提示为不是str类型数据,要写成这样) # print("排序之后:",insertion(collection)) endTime=time.time() time1=endTime-startTime
结果是多次实验后
第一次0(直接),第二次0,第一次比第二次多0
*)查看运算浪费的时间
结论:有区别,建议直接将运算式放入,不要用变量储存
d=[0] c=0 add=0 for i in range(100): startTime=time.time() for i in range(10000): c=(((3000-1)//2234)*22+99)//3 # print((((3000-1)//2234)*22+99)//3,end=',') endTime=time.time() time1=endTime-startTime startTime=time.time() a=(((3000-1)//2234)*22+99)//3 for i in range(10000): c=a # print(a,end=",") endTime=time.time() time2=endTime-startTime if d!=0: d.append(float('%.9f'%(time2-time1))) else: d[0]+=1 for i in d: add+=i print('运行了100轮,每次的时间差如下:%s。 平均时间是%.5f'%(d,add/100)) #结果 平均时间是0.01075 平均时间是0.01865 平均时间是0.01066 平均时间是0.00481 平均时间是0.01712 平均时间是-0.00101