用Python实现各种排序算法
最后更新于:2022-04-01 07:27:55
#### 1.冒泡排序
比较相邻的元素大小,将小的前移,大的后移,就像水中的气泡一样,最小的元素经过几次移动,会最终浮到水面上。
~~~
def bubble(list):
for i in range(len(list)):
for j in range(0,len(list)-1-i):
if list[j] > list[j+1]:
list[j],list[j+1]=list[j+1],list[j]
if name == 'main':
list1 = [2,3,5,7,8,9,6,54,1,42]
bubble(list1)
print(list1)
~~~
#### 2.插入排序
将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
~~~
def insertsort(list):
if list != None:
if len(list) == 1:
pass
else:
for i in range(1,len(list)):#start with second item.
temp = list[i]
for j in range(i):
if list[j]>list[i]:
for k in range(i,j,-1):#
list[k]= list[k-1]
list[j] = temp
if name == 'main':
list1 = [3,2,7,5,8,9,6,54,1,42]
insertsort(list1)
print(list1)
~~~
#### 3.快速排序
(1)这里实现第一轮排序,不妨称第一个元素为锚
(2)i,j分别指向待排序序列的第一和最后一个元素
(3)j与锚比较,若大于锚则左移,直到小于锚的元素停下,与i指向元素交换,i后移
(4)接着,i与锚比较,若小于则右移,直到大于锚的元素停下,与j指向的元素交换,j前移,
(5)i,j交替移动,i==j时,锚temp到达最终位置。
~~~
L = [90,89,78,67,56,45,34,23,12,0]
def first_sort(numbers,i,j):
temp = numbers[i]
while i!=j:
while i<j and numbers[j]>temp:
j = j - 1
if i < j
numbers[i] = numbers[j]
i = i + 1
while i < j and numbers[i]<temp:
i = i + 1
if i <j:
numbers[j] = numbers[i]
j = j - 1
numbers[i] = temp
return i
def quick_sort(numbers,i,j):
if i<j:
middle = first_sort(numbers,i,j)
quick_sort(numbers,i,middle-1)
quick_sort(numbers,middle+1,j)
if name=='main':
quick_sort(L,0,len(L)-1)
print
~~~
#### 4.选择排序
从所有序列中先找到最小的,然后放到第一个位置。之后再看剩余元素中最小的,放到第二个位置……以此类推,就可以完成整个的排序工作。
~~~
def selectionsort(list):
if list != None:
for i in range(len(list)):
min = i
for j in range(i+1,len(list)):
if list[min] > list[j]:
min = j
if min != i:
list[min],list[i] = list[i],list[min]
if name == 'main':
list1 = [2,3,5,7,8,9,6,54,1,42]
selectionsort(list1)
print(list1)
~~~
#### 5.希尔排序
先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。
~~~
test=[9,2,3,5,7]
def ShellSort(data,flag):
'''
data: list,to be sorted
flag: 0->asc,1->desc
return a new sorted list
'''
retData=[]
#copy data to retData
for item in data:
retData.append(item)
#sort retData
count=len(retData)
step=count/2;
while step>0:
i=0
while i<count:
j=i+step
while j<count:
t=retData.pop(j)
k=j-step
#asc
if flag==0:
while k>=0:
if t>=retData[k]:
retData.insert(k+1, t)
break
k=k-step
if k < 0:
retData.insert(0, t)
#desc
elif flag==1:
while k>=0:
if t<=retData[k]:
retData.insert(k+1, t)
break
k=k-step
if k<0:
retData.insert(0, t)
j=j+step
i=i+1
step=step/2
return retData
data=ShellSort(test,0)
print 'Asc:',data
data=ShellSort(test,1)
print 'Desc:',data
~~~
Python:面向对象的“开闭原则”和“鸭子类型”
最后更新于:2022-04-01 07:27:52
#### 开闭原则
开闭原则(OCP)是面向对象设计中“可复用设计”的基石,是面向对象设计中最重要的原则之一,其它很多的设计原则都是实现开闭原则的一种手段。
1988年,勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造(Object Oriented Software Construction)》中提出了开闭原则,它的原文是这样:“Software entities should be open for extension,but closed for modification”。翻译过来就是:“软件实体应当对扩展开放,对修改关闭”。这句话说得略微有点专业,我们把它讲得更通俗一点,也就是:软件系统中包含的各种组件,例如模块(Modules)、类(Classes)以及功能(Functions)等等,应该在不修改现有代码的基础上,引入新功能。开闭原则中“开”,是指对于组件功能的扩展是开放的,是允许对其进行功能扩展的;开闭原则中“闭”,是指对于原有代码的修改是封闭的,即不应该修改原有的代码。
#### 鸭子类型
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。
这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。
Python中的实例:
~~~
#定义Animal类,有run()方法
class Animal(object):
def run(self):
print('It is running!!!')
#Dog/Cat分别继承Animal类
class Dog(Animal):
def run(self):
print('Dog is running!!!')
class Cat(Animal):
def run(self):
print('Cat is running!!!')
#Child不继承Animal类
class Child(object):
def run(self):
print('Child is running!!!')
#定义函数run_twice(),该函数接受Animal类型的变量
def run_twice(Animal):
Animal.run()
Animal.run()
dog = Dog()
dog.run()
cat = Cat()
cat.run()
child = Child()
child.run()
#run_twice()函数接收是Animal类型的Dog、Cat
run_twice(dog)
run_twice(cat)
#run_twice()函数接收不是Animal类型的Child
run_twice(child)
~~~
Python安装pip和easy_installer工具
最后更新于:2022-04-01 07:27:50
1.在以下地址下载最新的PIP安装文件 [http://pypi.python.org/pypi/pip#downloads](http://pypi.python.org/pypi/pip#downloads)
2.下载Windows的easy installer,然后安装
[http://pypi.python.org/pypi/setuptools](http://pypi.python.org/pypi/setuptools)
参考:[【Python】如何安装easy_install?](http://jingyan.baidu.com/article/b907e627e78fe146e7891c25.html)
3.命令行工具cd切换到pip的目录,找到setup.py文件,然后输入python setup.py install,运行即可(之所以能运行这步,是因为之前安装的setuptools工具,以后就可以随意安装python的库了,只要找对setup.py文件的路径,运行上述命令,就可以方便的安装了)
4.把python的安装路径添加到环境变量path中,例如G:\python2.6\Scripts
5.完成!
Python:函数式编程
最后更新于:2022-04-01 07:27:48
#### 高阶函数
##### 函数名也是变量
在Python中,变量可以直接指向函数,函数名只不过是指向该函数运行方法的一个变量,例如:
~~~
f = abs
f(-10)
~~~
运行结果是10,说明此时变量f已经指向了函数abs
实例:
~~~
def add(x,y,f):
return f(x) + f(y)
x = 10
y = -5
f = abs
add(x,y,f)
~~~
把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
##### map/reduce
Map/Reduce简单来说,就是先map:分割数据进行处理,再reduce:将分割的数据处理结果合并,在hadoop会涉及到,以后总结的时候详细说明。
可以参考这篇文章:[用通俗易懂的大白话讲解Map/Reduce原理](http://blog.csdn.net/lifuxiangcaohui/article/details/22675437)
现在看一下Python中的map/reduce:
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现。
~~~
def f(x):
return x*x
r = map(f,[1,2,3,4,5,6,7,8,9])
list(r)
~~~
把list中的所有数字转化成字符串:
~~~
r = map(str,[1,2,3,4,5,6,7,8,9])
~~~
再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比如我想做一个累加的计算,从1加到10,可以这样写:
~~~
from functools import reduce
def add(x, y):
return x + y
reduce(add,[1,2,3,4,5,6,7])
~~~
练习:
~~~
def fn(x, y):
return 10*x+y
a = reduce(fn,[1,2,3,4,5,6])
~~~
练习:
利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:[‘adam’, ‘LISA’, ‘barT’],输出:[‘Adam’, ‘Lisa’, ‘Bart’]
~~~
def normalize(name):
return name[0].upper() + name[1:].lower()
L1 = ['adam', 'LISA', 'barT']
L2 = list(map(normalize, L1))
print(L2)
~~~
练习:Python提供的sum()函数可以接受一个list并求和,请编写一个prod()函数,可以接受一个list并利用reduce()求积
~~~
from functools import reduce
def prod(L):
def plus(x,y):
return x*y
return reduce(plus,L)
print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9]))
~~~
练习:利用map和reduce编写一个str2float函数,把字符串’123.456’转换成浮点数123.456
~~~
from functools import reduce
def str2float(s):
def a(x,y):
return x*10 + y
def b(x,y):
return x/10 + y
def char2int(s):
return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
i = s.find('.')
return (reduce(a,map(char2int,s[:i])) + reduce(b,map(char2int,s[-1:i:-1]))/10)
print('str2float(\'123.456\') =', str2float('123.456'))
~~~
Python高级特性:切片;迭代;列表生成式;生成器;迭代器
最后更新于:2022-04-01 07:27:46
#### 切片
在Python中常见的操作是取一个list或tuple的一部分,比如一个list如下:
~~~
L = ['red','yellow','black','orange','white','green','blue']
~~~
取前三个元素的操作,除了用循环,还可以用切片:
~~~
L[0:3]
#表示从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素
print(L[-2:])
#表示取倒数后两个
~~~
实例:
~~~
#定义从1到100的序列
L = list(range(100))
#取前十个,同时隔一个数取一个
print(L[:10:2])
~~~
#### 迭代
一般程序语言的迭代使用for。Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。
除了list这种有下标的数据类型,还有例如dict这样的无下标的,也可以使用for迭代。
~~~
d = {'funny':1,'lucky':2,'daddy':3}
for key in d:
print(key)
#因为dict的存储不是按照list的方式顺序排列,所以,迭代出的结果顺序很可能不一样。
~~~
同时value也可以迭代。
~~~
for values in d.values():
print(values)
~~~
如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
~~~
>>> from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False
~~~
#### 列表生成式(List Comprehensions)
python内置了功能强大的列表生成式。
实例:
~~~
l = list(range(1,11))
print(l)
~~~
输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
实例:输出1-10 的平方
~~~
L = []
for x in range(1,11):
L.append(x*x)
~~~
练习:
L1 = [‘Hello’, ‘World’, 18, ‘Apple’, None]
期待输出: [‘hello’, ‘world’, ‘apple’]
code:
~~~
L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = []
for x in L1:
if isinstance(x,str):
L2.append(x.lower())
print(L2)
~~~
#### 生成器
在Python中,一边循环一边计算的机制,称为生成器:generator,即只计算出要使用的数,节省空间。
要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:
~~~
L = [x * x for x in range(10)]
L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
g = (x * x for x in range(10))
g
<generator object <genexpr> at 0x1022ef630>
~~~
打印generator:
~~~
g = (x*x for x in range(10))
for x in g:
print(x)
~~~
练习
杨辉三角定义如下:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list.
~~~
def triangles():
L = [1]
while True:
yield L
L1 = L[:]
L = []
i = 0
while i < len(L1) - 1:
L.append(L1[i] + L1[i+1])
i = i + 1
L.insert(0, 1)
L.append(1)
n = 0
for t in triangles():
print(t)
n = n + 1
if n == 10:
break
~~~
Python:函数
最后更新于:2022-04-01 07:27:43
#### 默认参数
Python中的函数定义以及参数的使用:
定义函数要使用def+函数名
~~~
def enroll(name,gender,age = 6,city = 'Beijing'):
print(name)
print(gender)
print(age)
print(city)
enroll('Billy','Six')
~~~
这里使用了默认参数,降低了函数调用的难度,而一旦需要更复杂的调用时,又可以传递更多的参数来实现。无论是简单调用还是复杂调用,函数只需要定义一个。
默认参数的坑:先定义一个函数,传入一个list,添加一个END再返回:
~~~
def add_end(L=[]):
L.append('END')
return L
add_end([1,2,3])
~~~
正常调用的时候没有错误,但是如果使用默认参数多次调用的话:
~~~
print(add_end())
print(add_end())
print(add_end())
print(add_end())
~~~
结果会是:
[‘END’]
[‘END’, ‘END’]
[‘END’, ‘END’, ‘END’]
[‘END’, ‘END’, ‘END’, ‘END’]
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
要修改上面的例子,可以使用None这个不变对象来实现:
~~~
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
~~~
#### 可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
我们以数学题为例子,给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……。
要定义出这个函数,我们必须确定输入的参数。由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
~~~
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
~~~
但是调用的时候,需要先组装出一个list或tuple:
calc([1, 2, 3])
14
calc((1, 3, 5, 7))
84
如果利用可变参数,调用函数的方式可以简化成这样:
calc(1, 2, 3)
14
calc(1, 3, 5, 7)
84
所以,我们把函数的参数改为可变参数:
~~~
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
~~~
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
calc(1, 2)
5
calc()
0
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
nums = [1, 2, 3]
calc(nums[0], nums[1], nums[2])
14
这种写法当然是可行的,问题是太繁琐,所以Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:
nums = [1, 2, 3]
calc(*nums)
14
*nums表示把nums这个list的所有元素作为可变参数传进去。这种写法相当有用,而且很常见。
转载自 :[廖雪峰的官方网站:函数的参数](http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000)
Python:循环、条件判断
最后更新于:2022-04-01 07:27:41
#### 循环
Python的循环有两种,一种是for…in循环,依次把list或tuple中的每个元素迭代出来:
~~~
names = ['Harry','Potter','Jack']
for names in names:
print(names)
~~~
输出结果:
Harry
Potter
Jack
所以for x in …循环就是把每个元素代入变量x,然后执行缩进块的语句。
例:计算1-10 的和:
~~~
sum = 0
for x in [1,2,3,4,5,6,7,8,9,10]:
sum = sum + x
print(sum)
~~~
或者使用python中的range()函数,可以生成一个小于指定整数的序列。
~~~
sum = 0
for x in range(11):
sum = sum + x
print(sum)
~~~
第二种是while循环。
要计算100以内所有奇数之和:
~~~
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
~~~
练习
请利用循环依次对list中的每个名字打印出Hello, xxx!:
~~~
names = ['Harry','Potter','Jack']
for names in names:
print('Hello,',names)
~~~
#### 条件判断
elif:
elif是else if的缩写,完全可以有多个elif,所以if语句的完整形式就是:
~~~
if <条件判断1>:
<执行1>
elif <条件判断2>:
<执行2>
elif <条件判断3>:
<执行3>
else:
<执行4>
~~~
实例:
小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:
低于18.5:过轻
18.5-25:正常
25-28:过重
28-32:肥胖
高于32:严重肥胖
用if-elif判断并打印结果:
~~~
height = float(input('输入身高:'))
weight = float(input('输入体重:'))
num = height*height
num = weight/num
if num<18.5:
print('过轻')
elif num<25:
print('正常')
elif num<28:
print('过重')
elif num<32:
print('肥胖')
elif num>32:
print('严重肥胖')
~~~
python中的list和tuple
最后更新于:2022-04-01 07:27:39
### python的输入和输出
输出:
~~~
print('hello, world')
~~~
多个字符串的输出用逗号隔开即可。
~~~
print('hello, world','how are you','fine,thank you')
~~~
输入:
~~~
name = input('please input your name:')
print('hello,',name)
~~~
在这个例子中name这个变量直接被赋值,这里值得注意的是此时输入的是字符串类型,如果需用到其他数据类型需要做数据类型的转换。
~~~
#指定list
allnames = ['Harry','Roan','Billy']
#变量allnames就是一个list,用len()函数可以获得list元素的个数
print(len(allnames))
#可以全部或分别获取list中的元素
print(allnames)
print(allnames[0])
#元素的插入
allnames.insert(1,'Lucy')
print(allnames)
#元素的删除
allnames.pop()#直接删除末尾元素
print(allnames)
allnames.pop(2)#删除指定位置元素
print(allnames)
#指定位置元素可以直接替换
allnames[1] = 'David'
print(allnames)
~~~
另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改。当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来。
~~~
#tuple的定义
t = (1,2,3)
print(t)
#当只有一个元素的时候,必须必须加一个逗号,消除歧义
t =(1,)
print(t)
~~~
练习
请用索引取出下面list的指定元素:
~~~
L = [
['Apple', 'Google', 'Microsoft'],
['Java', 'Python', 'Ruby', 'PHP'],
['Adam', 'Bart', 'Lisa']
]
~~~
打印Apple:
~~~
print(L[0][0])
~~~
打印Python:
~~~
print(L[1][1])
~~~
打印Lisa:
~~~
print(L[2][2])
~~~
总结:list和tuple是Python内置的有序集合,一个可变,一个不可变。
python的安装和编译器的选择
最后更新于:2022-04-01 07:27:36
决定用一个月的时间学习python,目标是学习完后可以用python做一个小型项目。
python的安装和下载:直接搜python,到官网下载安装包即可,安装完毕后可以用系统命令行测试下,cmd—>python,如果出现python的版本信息则表示安装成功,如果显示python不是内部或外部命令XXXXX.......直接卸载重装就好,是因为在安装python的时候没有勾选Add python.exe to Path.
然后可以直接在命令行下测试python小程序:输入20+20,回车,会直接得出结果;输入python的打印函数print('hello world');会显示hello world。
下面是编译器的选择,我选择的是很受好评的PyCharm,同样安装好后建立工作空间即可。
总而言之,python的安装很容易,同时环境变量会自动配置,编译器的选择也较多,上手容易,这一点比Java要好。
前言
最后更新于:2022-04-01 07:27:34
> 原文出处:[编程语言专栏文章](http://blog.csdn.net/column/details/tibpy.html)
> 作者:[郑泽辉](http://blog.csdn.net/tryitboy)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
#30天python全接触
> 学习python的点点滴滴。