python语言做法_python学习笔记(十六)

## Python语言进阶

### 重要知识点

- 生成式(推导式)的用法

```Python

prices = {

'AAPL': 191.88,

'GOOG': 1186.96,

'IBM': 149.24,

'ORCL': 48.44,

'ACN': 166.89,

'FB': 208.09,

'SYMC': 21.29

}

# 用股票价格大于100元的股票构造一个新的字典

prices2 = {key: value for key, value in prices.items() if value > 100}

print(prices2)

```

> 说明:生成式(推导式)可以用来生成列表、集合和字典。

- 嵌套的列表的坑

```Python

names = ['关羽', '张飞', '赵云', '马超', '黄忠']

courses = ['语文', '数学', '英语']

# 录入五个学生三门课程的成绩

# 错误 - 参考http://pythontutor.com/visualize.html#mode=edit

# scores = [[None] * len(courses)] * len(names)

scores = [[None] * len(courses) for _ in range(len(names))]

for row, name in enumerate(names):

for col, course in enumerate(courses):

scores[row][col] = float(input(f'请输入{name}的{course}成绩: '))

print(scores)

```

[Python Tutor](http://pythontutor.com/) - VISUALIZE CODE AND GET LIVE HELP

- `heapq`模块(堆排序)

```Python

"""

从列表中找出最大的或最小的N个元素

堆结构(大根堆/小根堆)

"""

import heapq

list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92]

list2 = [

{'name': 'IBM', 'shares': 100, 'price': 91.1},

{'name': 'AAPL', 'shares': 50, 'price': 543.22},

{'name': 'FB', 'shares': 200, 'price': 21.09},

{'name': 'HPQ', 'shares': 35, 'price': 31.75},

{'name': 'YHOO', 'shares': 45, 'price': 16.35},

{'name': 'ACME', 'shares': 75, 'price': 115.65}

]

print(heapq.nlargest(3, list1))

print(heapq.nsmallest(3, list1))

print(heapq.nlargest(2, list2, key=lambda x: x['price']))

print(heapq.nlargest(2, list2, key=lambda x: x['shares']))

```

- `itertools`模块

```Python

"""

迭代工具模块

"""

import itertools

# 产生ABCD的全排列

itertools.permutations('ABCD')

# 产生ABCDE的五选三组合

itertools.combinations('ABCDE', 3)

# 产生ABCD和123的笛卡尔积

itertools.product('ABCD', '123')

# 产生ABC的无限循环序列

itertools.cycle(('A', 'B', 'C'))

```

- `collections`模块

常用的工具类:

- `namedtuple`:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。

- `deque`:双端队列,是列表的替代实现。Python中的列表底层是基于数组来实现的,而deque底层是双向链表,因此当你需要在头尾添加和删除元素是,deque会表现出更好的性能,渐近时间复杂度为$O(1)$。

- `Counter`:`dict`的子类,键是元素,值是元素的计数,它的`most_common()`方法可以帮助我们获取出现频率最高的元素。`Counter`和`dict`的继承关系我认为是值得商榷的,按照CARP原则,`Counter`跟`dict`的关系应该设计为关联关系更为合理。

- `OrderedDict`:`dict`的子类,它记录了键值对插入的顺序,看起来既有字典的行为,也有链表的行为。

- `defaultdict`:类似于字典类型,但是可以通过默认的工厂函数来获得键对应的默认值,相比字典中的`setdefault()`方法,这种做法更加高效。

```Python

"""

找出序列中出现次数最多的元素

"""

from collections import Counter

words = [

'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes',

'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around',

'the', 'eyes', "don't", 'look', 'around', 'the', 'eyes',

'look', 'into', 'my', 'eyes', "you're", 'under'

]

counter = Counter(words)

print(counter.most_common(3))

```

### 数据结构和算法

- 算法:解决问题的方法和步骤

- 评价算法的好坏:渐近时间复杂度和渐近空间复杂度。

- 渐近时间复杂度的大O标记:

- gif.latex?O(c) - 常量时间复杂度 - 布隆过滤器 / 哈希存储

- gif.latex?O(log_2n) - 对数时间复杂度 - 折半查找(二分查找)

- gif.latex?O(n) - 线性时间复杂度 - 顺序查找 / 计数排序

- gif.latex?O(n*log_2n) - 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)

- gif.latex?O(n%5E2) - 平方时间复杂度 - 简单排序算法(选择排序、插入排序、冒泡排序)

- gif.latex?O(n%5E3) - 立方时间复杂度 - Floyd算法 / 矩阵乘法运算

- gif.latex?O(2%5En) - 几何级数时间复杂度 - 汉诺塔

- gif.latex?O(n!) - 阶乘时间复杂度 - 旅行经销商问题 - NPC

![](./res/algorithm_complexity_1.png)

![](./res/algorithm_complexity_2.png)

- 排序算法(选择、冒泡和归并)和查找算法(顺序和折半)

```Python

def select_sort(items, comp=lambda x, y: x < y):

"""简单选择排序"""

items = items[:]

for i in range(len(items) - 1):

min_index = i

for j in range(i + 1, len(items)):

if comp(items[j], items[min_index]):

min_index = j

items[i], items[min_index] = items[min_index], items[i]

return items

```

```Python

def bubble_sort(items, comp=lambda x, y: x > y):

"""冒泡排序"""

items = items[:]

for i in range(len(items) - 1):

swapped = False

for j in range(len(items) - 1 - i):

if comp(items[j], items[j + 1]):

items[j], items[j + 1] = items[j + 1], items[j]

swapped = True

if not swapped:

break

return items

```

```Python

def bubble_sort(items, comp=lambda x, y: x > y):

"""搅拌排序(冒泡排序升级版)"""

items = items[:]

for i in range(len(items) - 1):

swapped = False

for j in range(len(items) - 1 - i):

if comp(items[j], items[j + 1]):

items[j], items[j + 1] = items[j + 1], items[j]

swapped = True

if swapped:

swapped = False

for j in range(len(items) - 2 - i, i, -1):

if comp(items[j - 1], items[j]):

items[j], items[j - 1] = items[j - 1], items[j]

swapped = True

if not swapped:

break

return items

```

```Python

def merge(items1, items2, comp=lambda x, y: x < y):

"""合并(将两个有序的列表合并成一个有序的列表)"""

items = []

index1, index2 = 0, 0

while index1 < len(items1) and index2 < len(items2):

if comp(items1[index1], items2[index2]):

items.append(items1[index1])

index1 += 1

else:

items.append(items2[index2])

index2 += 1

items += items1[index1:]

items += items2[index2:]

return items

def merge_sort(items, comp=lambda x, y: x < y):

return _merge_sort(list(items), comp)

def _merge_sort(items, comp):

"""归并排序"""

if len(items) < 2:

return items

mid = len(items) // 2

left = _merge_sort(items[:mid], comp)

right = _merge_sort(items[mid:], comp)

return merge(left, right, comp)

```

```Python

def seq_search(items, key):

"""顺序查找"""

for index, item in enumerate(items):

if item == key:

return index

return -1

```

```Python

def bin_search(items, key):

"""折半查找"""

start, end = 0, len(items) - 1

while start <= end:

mid = (start + end) // 2

if key > items[mid]:

start = mid + 1

elif key < items[mid]:

end = mid - 1

else:

return mid

return -1

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值