*)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