enumerate在字典上是枚举、列举的意思
对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值.
enumerate()使用
如果对一个列表,既要遍历索引又要遍历元素时,首先可以这样写:
list1 = ["这", "是", "一个", "测试"]
for i in range (len(list1)):
print i ,list1[i]
上述方法有些累赘,利用enumerate()会更加直接和优美:
list1 = ["这", "是", "一个", "测试"]
for index, item in enumerate(list1):
print index, item
>>>
0 这
1 是
2 一个
3 测试
enumerate还可以接收第二个参数,用于指定索引起始值,如:
list1 = ["这", "是", "一个", "测试"]
for index, item in enumerate(list1, 1):
print index, item
>>>
1 这
2 是
3 一个
4 测试
def hanoi(n, a, b, c):
if n>0:
hanoi(n-1, a, c, b)
print('moving from %s to %s'%(a,c))
hanoi(n - 1, b, a, c)
hanoi(4, 'A', 'B', 'C')
def func(n):
# 给递归一个出口 第一位和第二位都是1
if n == 1:
return 1
if n == 2:
return 3
else:
# 从第三位开始 返回上一个数加上上一个数
return 2*func(n-1) + 1
res = func(64)
print(res)
二分查找:在有序列表中所作的一个查找方法。
def binary_search(li, val):
left = 0
right = len(li)-1
while left<=right: #候选区有值
mid = (left + right) // 2
if li[mid] == val:
return mid
elif li[mid] > val: #待查找的值在mid左侧。
right = mid - 1
else: #待查找的值在mid右侧。
left = mid + 1
else:
return None
li = [1,2,3,4,5,6,7,8,9]
print(binary_search(li , 3))
二分查找的复杂度为log n .比线性查找快。内置列表查找函数index()是线性查找,因为二分查找必须是顺序表。
排序之后二分查找和线性查找的时间区别。
排序 内置排序函数为sort()
Low B 三人组 冒泡、选择、插入排序。 NB三人组 快速、堆、并归排序。 其他排序 希尔排序、计数排序、基数排序。
冒泡排序 一个一个对比,向上交换。一趟之后,最大的数字一定到最上面。从0开始技术,需要n-1趟。
一趟完成后,无序区减少一个数,有序区增加一个数。关键点:趟、无序区范围(n-i-1)。
import random
def bubble_sort(li):
for i in range(len(li) - 1): #i表示第i趟。
exchange = False #每一趟加一个标志位
for j in range(len(li)-1-i):
if li[j] > li[j+1]:
li[j], li[j+1] = li[j+1], li[j]
exchange = True #交换了就设置成True.
print(li)
if not exchange: #每一趟排完之后,如果exchange还是false就结束。说明没有发生交换。
return
#时间复杂度O(n^2)
li = [random.randint(0,100) for i in range(10)] #用random模块列表生成式生成一个随机整数。
print(li)
bubble_sort(li)
print(li)
选择排序。遍历一遍,选最小的拿出来。
def sel_sort_simple(li):
li_new = []
for i in range(len(li)): #选最小的出来需要遍历n遍。
min_val = min(li)
li_new.append(min_val)
li.remove(min_val)
print(li)
print(li_new)
return li_new
import random
#这个算法不好。因为使用了两个列表,占内存大。而且 min操作和remove操作都是时间复杂度为O(n)的操作。时间复杂度为O(n^2),remove和min算到一个n里面。
import random
def sel_sort(li):
for i in range(len(li)-1): #一共需要n-1趟。
min_loc = i
for j in range(i+1, len(li)): #无序区是i到最后。
if li[j] < li[min_loc]:
min_loc = j
li[i], li[min_loc] = li[min_loc], li[i]
print(li)
li = [random.randint(0, 100) for i in range(10)]
print(li)
sel_sort(li)
print(li)
#最需要注意的是无序区最小数的位置。时间复杂度O(n^2).
归位函数的实现过程:
lowb 插入排序 NB快速排序
#插入排序,就像摸牌的过程.寻找插入的位置。
def insert_sort(li):
for i in range(1, len(li)): # i表示摸到的牌的下标,可以从1的位置可以摸牌。
tmp = li[i]
j = i - 1 # j指的是手里的牌。
while li[j] > tmp and j >= 0: # 比较j-1和刚摸到的j的大小,就往左挪一个。
li[j+1] = li[j]
j -= 1
li[j+1] = tmp
print(li)
li = [3, 2, 4, 1, 5, 6]
insert_sort(li)
print(li)
# 插入排序时间复杂度为O(n^2). Low B三人组的排序效率都是O(n^2).实际运用过程中效率太低。
# NB三人组 快速排序
# 框架
def partition(li, left, right): # 写归位函数
tmp = li[left]
while left < right: # 只要左边箭头比右边箭头的位置小,就继续执行循环。当左边有空位,就从右边开始找
while left < right and li[right] >= tmp: # 找比tmp小的数。
right -= 1 # 往左看一位。
li[left] = li[right] # 把右边的值写到左边的空位上。
print(li)
while li[left] <= tmp and left < right:
left += 1
li[right] = li[left] # 把左边的值写到右边的空位上。
print(li)
li[left] = tmp # 把tmp归位。
return left
def quick_sort(li, left, right):
if left < right: # 有两个或者以上的数字个数用递归。
mid = partition(li, left, right) # 归位函数。
quick_sort(li, left, mid-1) # 递归排mid左边的数
quick_sort(li, mid+1, right) # 递归排mid右边的数
# partition 的过程是左右两个指针往中间移动。
li = [5, 7, 4, 1, 3, 6, 2, 9, 8]
quick_sort(li, 0, len(li)-1)
print(li)
# 快速排序的效率是O(nlogn)。涉及到递归,一共n层,每层的复杂度是logn。
# 当用10000个整数进行排序时,冒泡排序需要12秒,而快速排序需要0.03秒。但是快速排序有最坏情况出现(每次只少一个数,这时系统复杂度是n^2),而且递归大大占用系统资源。
# 也可以用随机的一个数代替第一个数,缓解最坏情况。最坏情况可能性很低。
func3先打印321, fun4先打印123