一些无聊的测试

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

#若是不加这个_的话
def test1():
    return 1,2

a=test1()
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。\n平均时间是%.5f'%(d,add/100))

#结果
平均时间是0.01075
平均时间是0.01865
平均时间是0.01066
平均时间是0.00481
平均时间是0.01712
平均时间是-0.00101

  

def test1():
    return 1,2

a,_=test1()
print(a,_)
posted @ 2019-07-03 18:37  凌晨四点的蓝  阅读(275)  评论(0编辑  收藏  举报