Python常用算法
1、普通排序:
sorted()方法排序后生成新的列表,不会改变原来的列表。list.sort()方法排序后会改变原来的列表
#encoding: utf-8 alist = [0, 10, 88, 19, 9, 1] #print(sorted(alist)) #print(sorted(alist, reverse=True)) alist.sort(reverse=True) print(alist)
2、冒泡排序:
#encoding: utf-8 def bubble_sort(lists): count = len(lists)-1 #获取数组长度 itemrange = range(count, 0, -1) #N个元素遍历N次 for index in itemrange: #第i个和第i+1个依次对比 for sub_index in range(index): #大的元素冒上去 if lists[sub_index] > lists[sub_index+1]: lists[sub_index],lists[sub_index+1]=lists[sub_index+1],lists[sub_index] return lists alist = [0, 10, 88, 19, 9, 1] print(bubble_sort(alist))
3、快速排序:
#encoding: utf-8 def quick_sort(lists, left, right): #递归过程中,发现left和right一致时,停止递归,直接返回列表 if left >= right: return lists #定义游标 low = left high = right #取参考标志,最左边的元素 key = lists[low] while low < high: #从最右侧向左,依次和标志元素对比,如果右侧的元素大于标志元素 while low < high and lists[high] >= key: #右侧减1 high -= 1 #否则low赋high值 lists[low] = lists[high] #从最左侧向右,依次和标志元素对比,如果左侧的元素小于标志元素 while low < high and lists[low] <= key: #左侧加1 low += 1 #否则high赋low值 lists[high] = lists[low] #最后给high位置赋值 lists[high] = key #处理左侧元素 quick_sort(lists, left, low - 1) #处理右侧元素 quick_sort(lists, low + 1, right) return lists alist = [0, 10, 88, 19, 9, 1, 7] print(quick_sort(alist, 0, 6))
4、堆排序:
#encoding: utf-8 def heap_sort(lst): def sift_down(start, end): """最大堆调整""" root = start print "root %d start %d end %d"%(root, start, end) while True: child = 2 * root + 1 #print "child index: %d" % child #终止条件,孩子的索引值超过数组最大长度 if child > end: break #print "lst child value:%d" % lst[child] #确定最大的孩子节点的索引值 if child + 1 <= end and lst[child] < lst[child + 1]: child += 1 #print "child+1 index: %d" % child #孩子节点最大值和根节点交换 if lst[root] < lst[child]: lst[root], lst[child] = lst[child], lst[root] #print "lstroot %d" % lst[root], "lstchild %d" % lst[child] root = child #print "root %d" % root else: break print("-----------------创建最大堆------------------") # 创建最大堆 print(xrange((len(lst) - 2) // 2, -1, -1)) for start in xrange((len(lst) - 2) // 2, -1, -1): print "---->Loop start %d" % start sift_down(start, len(lst) - 1) print(lst) print("-----------------排序过程------------------") # 堆排序 for end in xrange(len(lst) - 1, 0, -1): #首尾交换 lst[0], lst[end] = lst[end], lst[0] #剩余重新堆排序 sift_down(0, end - 1) print(lst) return lst alist = [70, 60, 12, 40, 30, 8, 10] print(heap_sort(alist))
5、二分查找:
# encoding: utf-8 alist = [0, 1, 10, 88, 19, 9, 1] def binary_search(arr, start, end, hkey): if start > end: return -1 mid = start + (end - start) / 2 if arr[mid] > hkey: return binary_search(arr, start, mid - 1, hkey) if arr[mid] < hkey: return binary_search(arr, mid + 1, end, hkey) return mid alist = sorted(alist) print(alist) print binary_search(alist, 0, 6, 9)
有意思的程序
1、输出进度条
要想输出进度条,我们必须再原地输出才能保证他是一个进度条,最简单的办法就是再输出完毕后把光标移动到行首,继续在那里输出更长的进度条即可实现,新的更长的进度条把旧的短覆盖,就形成了动画效果。转义符 就可以把光标移动到行首而不换行,转义符 就把光标移动到行首并且换行。在python中,输出stdout(标准输出)可以使用sys.stdout.write
import time import sys for i in range(101): sys.stdout.write(' ') sys.stdout.write("%s%% |%s" %(int(i%101), int(i%101)*'#')) sys.stdout.flush() time.sleep(0.5) sys.stdout.write(' ')
2、输出乘法表
#左上三角格式输出九九乘法表
for i in range(1,10): for j in range(i,10): print("%d*%d=%2d" % (i,j,i*j),end=" ") print("")
注:乘法算式按行输出,与完整格式相比,内层循环范围为i~9,当外层循环的i逐渐递增时,每行输出的算式个数会越来越少,print("")表示换行,不输出这句的话输出的乘法表格式错乱。在Python中不能直接写print(" ")语句表示输出空格,必须添加end关键字,表示结尾以等号右边的内容输出,与后面的右上和左上的差别相似。
3、输出图形打印X型
O.....O
.O...O.
..O.O..
...O...
..O.O..
.O...O.
O.....O
for line in range(0,3): for star in range(line): print(".",end="") print("O",end="") for star in range(5-2*line): print(".",end="") print("O",end="") for star in range(line): print(".",end="") print() for line in range(1,2): for star in range(3): print(".",end="") print("O",end="") for star in range(3): print(".",end="") print() for line in range(2,-1,-1): for star in range(line): print(".",end="") print("O",end="") for star in range(5-2*line): print(".",end="") print("O",end="") for star in range(line): print(".",end="") print()
4、数字的四舍五入
#1、round(value, ndigits) 函数 print(round(1.23)) # 1 对小数点后第一位进行舍入 print(round(1.23,1)) # 1.2 对小数点后第二位进行舍入 print(round(10273,-1)) # 10270 # ndigits为负数时,舍入运算会作用在十位、百位、千位等上面 print(round(10.273,-1)) # 10.0 print(round(1.5)) # 2 print(round(2.5)) # 2 # 当一个值刚好在两个边界的中间的时候, round 函数返回离它最近的偶数。 也就是说,对1.5或者2.5的舍入运算都会得到2。 #2、如果你的目的只是简单的输出一定宽度的数, 只需要在格式化的时候指定精度即可 x=1.23456 print(format(x,"0.1f")) # 1.2 print(format(x,"0.2f")) # 1.23 print(format(x,"0.3f")) # 1.235 print("格式化精度{:0.4f}".format(x)) # 格式化精度1.2346 #3、链表方式 n=input() a=n.split('.') if int(a[-1][0])>=5: a[0]=int(a[0])+1 print(a[0])
5、杨辉三角定义如下:
1
/
1 1
/ /
1 2 1
/ / /
1 3 3 1
/ / / /
1 4 6 4 1
/ / / / /
1 5 10 10 5 1
#方法1: def triangles():#杨辉三角的一种生成方法 l = [1] while True : yield l for i in range ( 1,len (l) ) : l [i] = h [i] + h [i-1] l.append (1) h = l[:] ''' 当函数中出现了yield之后,该函数就不再被视为函数,而视为一个生成器。此时,整个函数被使用的语句流程会发生改变,一般的函数都是调用的时候从函数入口进,
发现return或函数执行完毕后返回,而生成器函数则是每次调用函数执行,执行到yield返回,下次再调用函数的时候从上次yield返回处继续执行。其次,range的
用法中如果是range(x,x)的形式,range依然返回空。故在上述代码的for循环中,由于在第一次试图循环的时候,后面的range要么是range(1,1)要么是range(0),
故都会成功避开i或者h没有实际值的循环,执行接下来的部分。当第二次试图循环开始时,i和h内的内容都已经满足条件了,所以就能正常运行了。 ''' #方法2: def triangles(): #用了list的生成式 L = [1] while True: yield L L= [(L + [0])[i] + ([0] + L)[i] for i in range(len(L)+1)]
6、卸载android手机中安装的所有第三方应用
import os def uninstall(): os.popen("adb wait-for-device") print( "start uninstall...") for packages in os.popen("adb shell pm list packages -3").readlines(): packageName = packages.split(":")[-1].splitlines()[0] os.popen("adb uninstall " + packageName) print "uninstall " + packageName + " successed." if __name__ == "__main__": uninstall() print( " ") print( "All the third-party applications uninstall successed.")
7、给安卓手机安装apk
#创建一文件夹,放入要安装的所有apk文件,创建一文件以py为后缀,复制以下代码: import os files = os.listdir(r'.') for file in files: # print(file + str(len(file)) + "---" + file[1]) # print(file[len(file)-3:len(file)]) # print(file[len(file)-3:len(file)]) if file[len(file)-3:len(file)] == "apk": #the string variable which is to storage the command will excute later string='adb install ' + """ + file + """ print(string) os.system(string) (注意:““” + file + """ , 这段代码,为了防止file的值含有空格,导致调用cmd命令安装失败,其次,apk不能为中文名,否则安装会出错) 双击文件,apk就已经安装到手机上了。
8、清理某路径下所有文件及文件夹
import os dirToBeEmptied = 'D:\_DataPythonos' #需要清空的文件夹 ds = list(os.walk(dirToBeEmptied)) #获得所有文件夹的信息列表 dsr = ds[::-1] #反转该列表,从最底层的文件夹开始清算 for d in dsr: #遍历该列表 print(d) #打印出列表项,观察规律 if d[2] != []: #如果该路径下有文件 for x in d[2]: #先将文件清理干净 os.remove(os.path.join(d[0], x)) for d in dsr: #再次遍历该列表 if d[1] != []: #如果该路径下有子文件夹 for y in d[1]: #将子文件夹清理干净 os.rmdir(os.path.join(d[0], y)) #之所以这么麻烦是因为 os.rmdir() 只能删除“空”文件夹。所以只能从最底层的文件夹开始清理,一级一级往上,才能清干净。
9、备份文件
import os import time #1.带备份文件路径或者完整地址加文件名 source = ['E:python\'] #2.文件备份地址 target_dir = 'E:\backup\' #3.使用日期创建一个文件路径 today = target_dir + time.strftime('%Y%m%d') now = time.strftime('%H%M%S') #4.判断这个路径是否存在,不存在新建路径 if not os.path.exists(today): os.mkdir(tody) print('Successfully created directory',tody) #5.备份后的文件路径加文件名os.sep = \ target = today + os.sep + now + '.zip' #6.使用zip命令压缩文件zip命令有一些选项和参数。-q选项用来表示zip命令安静地工作。 #-r选项表示zip命令对目录递归地工作,即它包括子目录以及子目录中的文件。 zip_command = "zip -qr {0} {1}".format(target, ''.join(source)) #7.通过给系统传递参数来执行压缩命令(压缩使用的是WinRAR所带文件rar.exe来执行压缩) if os.system(zip_command) == 0: print ('Successful backup to', target) else: print ('Backup FAILED')
10、单词统计(英文文本)
import re fin = open('test.txt', 'r') str = fin.read() reObj = re.compile('?(w+)?') # 匹配单词的开始或结束 words = reObj.findall(str) wordDict = dict() for word in words: if word.lower() in wordDict: wordDict[word.lower()] += 1 else: wordDict[word] = 1 for key, value in wordDict.items(): print('%s: %s' % (key, value))
11、生成随机激活码
import random, string forSelect = string.ascii_letters + "0123456789" def generate(count, length): # count = 200 # length = 20 for x in range(count): Re = "" for y in range(length): Re += random.choice(forSelect) print(Re) generate(200,20)
12、日期换算
import datetime import time def get_birthday_weekday(birthday_str=None): weekdays=['星期一','星期二','星期三','星期四','星期五','星期六','星期天'] if birthday_str==None: birthday=datetime.datetime.today() birthday_str=str(datetime.date.today()) else: birthday=time.strptime(birthday_str,"%Y %m %d") print('你的生日是:{0},{1}'.format(birthday_str,weekdays[int(time.strftime('%w',birthday))-1])) print('你的生日是:{0},{1}'.format(birthday_str, time.strftime('%w', birthday))) gf_birthday='2017 9 07' get_birthday_weekday(gf_birthday)
13、定时任务
import datetime,os,platform,time def run_task(): os_platfrom=platform.platform() if os_platfrom.startswith('Darwin'): print('该系统是MAC系统') os.system('ls') elif os_platfrom.startswith('Window'): print('该系统是win系统') os.system('dir') def timefun(sched_time): flag = 0 while True: now=datetime.datetime.now().strftime('%Y%m%d%H%M%S') if now==sched_time: run_task() time.sleep(1) flag=1 elif flag==0: flag=0 else: break return tms=datetime.datetime.strptime(input('请输入你要执行任务的时间(格式为:20180731200101):'), "%Y%m%d%H%M%S") sched_time=tms.strftime('%Y%m%d%H%M%S') print('任务将在{0}执行'.format(tms),' ') timefun(sched_time)
14、计算程序运行时间
#方法1 start = time.clock() run_fun() end = time.clock() print(end-start) #方法2 import time from functools import wraps import random def fn_timer(function): @wraps(function) def function_timer(*args, **kwargs): t0 = time.time() rr=function(*args, **kwargs) t1 = time.time() print("运行%s的总时间是:%s秒" %(function.__name__, str(t1 - t0))) return rr return function_timer @fn_timer def random_sort(n): return sorted([random.random() for i in range(n)]) random_sort(2000000)