一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习。
声明:本人学习是在扇贝编程通过网络学习的,相关的知识、案例来源于扇贝编程。如果使用请说明来源。
第28章 编程思维
学习笔记
卡耐基梅隆大学计算机教授 Jeannette Wing 提出 编程思维(Computational Thinking)的概念。编程思维 分为如下四点:
1 问题分解:把现实生活中的复杂问题,逐步拆分成容易解决的小问题;
2 模式识别:根据已有的知识和经验,找出新问题和以前解决过的问题的相似性;
3 抽象思维:将问题里涉及的数据抽象到数据结构(变量、列表、字典等),把数据处理过程可重复执行部分抽象成函数;
4 算法设计:根据前三步的分析成果,设计步骤,写出算法,从而解决问题。
编程思维的核心,不是编程语言,也不是语法,甚至不是算法或数据结构本身,而是如何分解问题,从中发现规律,建立解决问题的模型,并映射到合适的数据结构和算法上,然后才能根据算法写程序实现。
我们以计算文章难度为例:一篇英文文章中有很多单词,初始难度分为 0,每当出现一次生词就将难度分 +5,最终的难度分就代表这篇文章的难度。
问题分解
计算文章难度看上去很难,无从下手,我们来将它分解一下:
1 统计文章中的单词数
2 统计所有单词中生词的数
3 根据生词数计算难度分
模式识别
将问题分解后,接着我们开始着手解决这些小问题。“统计文章中的单词数”我们能联想到之前字符串中文本统计的做法。之前是按字统计,这次是词,本质上差别不大。
“统计所有单词中生词的数”和“根据生词数计算难度分”就是在所有单词中寻找生词,找到一个就给难度分 +5。无非就是循环、判断和求和的组合运用。在熟练掌握 Python 基础知识后,遇到问题我们能很快地判断出涉及到哪些知识点。
抽象思维
知道运用哪些知识点去解决问题后,我们还要完善代码,用更好的方式去解决问题。我们需要将问题抽象,比如文章、生词、词频、难度分等分别要用什么数据类型保存,整型?浮点型?字符串?列表还是字典?如何将代码封装成函数?
算法设计
前期的准备工作都做完了,数据准备好了,思路也理清楚了。接下来是最重要的一步:算法设计。我们要将之前的想法用代码写出来,从而解决问题。
我们之前说过,解决计算文章难度分为三步:统计文章中的单词数、统计所有单词中生词的数和根据生词数计算难度分。
“统计文章中的单词数”首先要将文章拆分成一个个单词,这里用到字符串方法里的 split() 方法,因为文章中有标点,我们还要用 replace() 方法将标点去除。
有了单词列表后我们可以统计出每个单词出现的次数,单词和次数这种一一对应的关系应该用字典存储,我们首先定义一个空字典,然后用循环遍历单词列表,如果字典里有了该单词,将对应的次数 +1,否则是第一次出现该单词,将对应的次数设为 1。
前面得到的单词列表是有问题的。因为有些单词的首字母是大写的,并不统一,因此在统计的时候会将大小写不一样的单词误认为是两个单词。所以我们需要将大小写统一,这里就调用字符串的 lower() 方法将其全都变成小写好了。
# 省略之前获取 word_list 代码
word_count = {}
for word in word_list:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print(word_count)
# 输出:{'this': 2, 'is': 11, 'a': 5, 'photograph': 3, ... 'into': 1}
有一个疑问,遍历整个文本进行统计之后,这些信息时如何进入字典的,比如列表有一个添加到里表中的命令,这里没有任何的向空字典中添加键和值的命令啊。
练习:统计文章难度:
“统计文章中的单词数”吗?除此之外我们再将代码封装成一个函数。
要求:
定义一个名为 get_word_count 的函数;
函数的参数为文章内容,返回值是每个单词出现次数的字典;
函数的功能是“统计文章中的单词数”;
调用函数并打印出单词出现次数的字典。
article = '''This is a photograph of our village.
Our village is in a valley.
It is between two hills.
The village is on a river.
Here is another photograph of the village.
My wife and I are walking along the banks of the river.
We are on the left.
There is a boy in the water.
He is swimming across the river.
Here is another photograph.
This is the school building.
It is beside a park.
The park is on the right.
Some children are coming out of the building.
Some of them are going into the park.
'''
def get_word_count(article): #包装成函数,代码的首行就是定义函数
word_count = {}
word_list = article.replace('.', ' ').lower().split() #针对串的操作可以一次性进行
# print(word_list)
for word in word_list:
#word_count.append(word)
if word in word_count:
word_count[word] = word_count[word] + 1
else:
word_count[word] = 1
return word_count #至关重要的一句话
print(get_word_count(article)) #定义和打印时,都带有参数article
练习:统计课文的难度终极
我们之前完成了计算文章难度的第一步,还剩统计所有单词中生词的数和根据生词数计算难度分,我们来完成它们。
我们再来看一看题目要求:一篇英文文章中有很多单词,初始难度分为 0,每当出现一次生词就将难度分 +5,最终的难度分就代表这篇文章的难度。
如果你已经有了思路,可以忽略下面的内容直接开始写代码了,如果你还是一头雾水,可以再思考一下然后看下面的提示。
提示:我们在统计生词数的同时可以进行难度分的计算,因此可以合并成一个 get_difficulty() 函数,参数为每个单词出现次数的字典和生词列表。初始难度分为 0,遍历生词列表,如果生词在单词出现次数的字典中,难度分增加 5 * 该单词出现的次数,最终即可得到难度分。
article = '''This is a photograph of our village.
Our village is in a valley.
It is between two hills.
The village is on a river.
Here is another photograph of the village.
My wife and I are walking along the banks of the river.
We are on the left.
There is a boy in the water.
He is swimming across the river.
Here is another photograph.
This is the school building.
It is beside a park.
The park is on the right.
Some children are coming out of the building.
Some of them are going into the park.
'''
# 三引号,定义一个多行文本的字符串。
new_words = [
'photograph',
'village',
'valley',
'between',
'hills',
'another',
'prep',
'wife',
'along',
'banks',
'water',
'swimming',
'building',
'park',
'into'
]
# 用一个列表来存放生词
def get_word_count(article): #统计单词及其个数的函数,参数是字符串
word_count = {}
word_list = article.lower().replace('.', '').split()
for word in word_list:
if word in word_count:
word_count[word] += 1 #这里的+=之间不可以有空格
else:
word_count[word] = 1
return word_count
#print(get_word_count(article))
#在此处print(word_count),会反馈没有定义,但是这里可以打印函数运行的结果
def get_difficulty(word_count, new_words): #定义一个计算难度的函数,要用到字典和列表
difficulty = 0
for word in new_words:
if word in word_count:
difficulty = difficulty + 5 * word_count[word] #直接在字典中提取键对应的值
return difficulty
word_count = get_word_count(article) #函数运行的结果赋值给word_count.
print(word_count) #次数打印结果和前面打印函数运行结果相同
difficulty = get_difficulty(word_count, new_words) #计算的难度结果赋值,以便下文打印
print(difficulty) #上一行直接打印难度函数结果也可以