2019-05-11 第三次

函数

为什们要使用函数?
1.代码重用,提高效率
2.模块独立,方便扩展、修改

1.定义一个函数格式

def  函数名 (参数列表):
     函数体

2.函数的命名规则

和变量一样,函数名由字母、数字、下划线组成,必须以字母或者下划线开头,且不能是保留字。

#定义一个最简单的无参数函数
def hello():
    print("Hello world")

#函数hello()的调用:
hello()
>>>
Hello world
#定义一个计算从1到num累加和的函数caculate_num()
def caculate_num(num):    
    res=0;
    for i in range(num+1):
        res+=i
    return res
#调用函数caculate_num() 求1~100的累加和:
print(caculate_num(100))
>>>
5050
  

3.形参和实参

形式参数——是虚拟变量,目的是在调用函数时接受实参
在python中,函数的形式参数无需指明类型
实际参数——调用时传给函数的参数
区别:形参是虚拟的不占据内存,只有在被调用的时候才分配内存单元;形参是一个变量,占用内存空间,数据单向由实参传递给形参

#定义一个求面积的函数
def area(weight,height):
    return weight*height
#调用
w=4
h=5
print(area(w,h))
>>>
20   

其中w和h是实际参数,weight和height是实际参数

4.函数文件相互调用

在一个项目中,往往每个人负责一部分功能,写成相应的函数. py文件,然后在main函数中用import命令可以实现文件中相关函数的互相调用 (类似于c++中的 #include<头文件>命令)

  • 步骤1.在新建的python file中定义要实现相关功能的函数
  • 步骤2.将文件重命名能体现其功能的样式

右击demo12文件,选择Refactor——>Rename
我们将这个包命名成cacul (命名不要和python库中已有的包重名)
然后点击 refactor ———>Do Refactor 完成重命名

  • 步骤3.在另一个python file中调用这个文件

在这个工程下新建一个测试文件test.py 用import命令调用相关函数

import cacul   #在测试文件中导入求和功能的文件
ans=cacul.caculate_num(100)  # 调用cacul包中的caculate_num()函数
print(ans)
>>>
5050
成功实现最简单的工程文件相互调用 ~bingo!

代码的改进

用列表推导式一行实现函数功能

def caculate_num2(num):
    return sum([i for i in range(1,num+1)])

print(caculate_num2(100))
>>>
5050

算法分析sum()函数的参数是可迭代的对象
先将1~100放在列表里,然后用sum函数直接求和 时间复杂度 为1
比进行n次for循环要高效得多

这种写法适用于交互式编程

Windows环境下 win+R 在运行窗口输入 cmd命令 进入DOS窗口 输入 python 即可开始编程

Linux环境下直接打开终端 同样输入python3 开始编程

5.必须参数和关键字参数

  • 1.必须参数必须以正确的方式传入,调用的时候必须和声明的时候顺序保持一致
def f(name,age):
    print('My name is %s ,I am %d years old'%(name,age))
#name、age为必须参数

f("xzy",20)
>>>
My name is  xzy ,I am 20 years old

f(20,"xzy")
>>>
My name is 20 ,I am xzy years old    #语义错误,gg

  • 2.使用关键字参数,调用函数的实际参数顺序可以与形参顺序不一致
    python解释器可以根据参数名字匹配参数值
f(age=40,name='刘强东')
>>>
My name is  刘强东 ,I am 40 years old
  • 3.默认参数 缺省参数没有传入,默认值会生效
    函数的默认参数必须放在最后
def f2(name,age,sex='male'):
    print('My name is %s ,I am %d years old,I am a  %s' % (name, age,sex))

f2(name='刘强东',age=40)  #是否显示指定参数,方便自己阅读为目的
>>>
My name is 刘强东 ,I am 40 years old,I am a  male

6.不定长参数

你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述2种参数不同,声明时不会命名。
基本语法如下:

def functionname([formal_args,],*var_args_tuple ):
    函数体
 return [expression]

加了星号(*)的变量名会存放所有未命名的变量参数。
不定长参数实例如下:

  • 带*的参数表示元组
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print("输出:")
   print arg1
   for var in vartuple:
      print var
   return;
 
# 调用printinfo 函数
printinfo( 10 );
printinfo( 70, 60, 50 );

>>>
输出:
10
输出:
70
60
50
变长参数
#将参数都放进一个元组中
def self_print(name,*a):   # *a为元组
    print("\n", type(a))
    print(name,a)


self_print("xzy",1,2,3,4,5,6)

>>>
<class 'tuple'>
xzy (1, 2, 3, 4, 5, 6)
  • **的参数表示字典
def d_self_print(**name):
    """将参数都放进字典中"""
    print(name)
d_self_print(last_name="刘",first_name="强东")

>>>
{'last_name': '刘', 'first_name': '强东'}

  • 用参顺序:位置参数->元组->字典

def mix(name,*t,**kw):
    print(name)
    print(t)
    print(kw)
mix("zhangsan",20,"neuq",gender='female')

匿名函数

  • lambda表达式
    语法:lambda 参数:表达式
    冒号前面是参数,可以有多个
    冒号后面是表达式,只能是一个表达式 不写return 返回值就是表达式的结果
  • 优点:减少代码量,更优雅
实例1:

最简单的lambdu表达式:

def rect(x,y):
    return x*y
ans=rect(4,5)
print(ans)

#使用lambda表达式有效地减少代码量:
res=lambda x,y:x*y
print(res(4,5))

>>>
20
20
实例2:

条件结构的lambda表达式:

def cal(x,y):
    if x>y:
        return x*y
    else:
        return x/y

cac=lambda x,y:x*y if x>y else x/y
实例3:

默认参数也能够在lambda参数中使用,就像在def中使用一样。

x = (lambda a="I", b="love", c="U": a + b + c)
x("I don't")
>>>
I don't love U
实例4:

列表排序中使用lambda表达式

  • 复习 sotred()函数
    描述:sorted() 函数对所有可迭代的对象进行排序操作。

sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

sorted语法:

sorted(iterable[, cmp[, key[, reverse]]])

参数说明:

  • iterable -- 可迭代对象。
  • cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
  • key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
    reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
>>>a = [5,7,6,3,4,1,2]
>>> b = sorted(a)       # 保留原列表
>>> a 
[5, 7, 6, 3, 4, 1, 2]
>>> b
[1, 2, 3, 4, 5, 6, 7]
 
>>> L=[('b',2),('a',1),('c',3),('d',4)]
>>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1]))   # 利用cmp函数
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
>>> sorted(L, key=lambda x:x[1])               # 利用key
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
 
 
>>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>> sorted(students, key=lambda s: s[2])            # 按年龄排序
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
 
>>> sorted(students, key=lambda s: s[2], reverse=True)       # 按降序
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
>>>

关于sorted的用法,详情请参考https://www.runoob.com/python/python-func-sorted.html

进入正题
用lambda表达式进行列表排序:

#新建一个列表,列表中的每一个元素都是存储姓名、年龄信息的元组
stus=[
      {'name':'zhangsan','age':33},
      {'name':'lisi','age':12},
      {'name':'wangwu','age':53},
      {'name':'zhaoiu','age':18},
      {'name':'tianqi','age':77}
     ]
print('排序前:',stus)

#以列表staus的元组元素的年龄对应的值为依据 从大到小排序
res = sorted(stus,key=lambda x: x['age'], reverse=True)  
print('年龄排序后',res)
res = sorted(stus,key=lambda x: x['name'])
print('name排序后',res)
>>>
排序前 [{'name': 'zhangsan', 'age': 33}, {'name': 'lisi', 'age': 12}, {'name': 'wangwu', 'age': 53}, {'name': 'zaoliu', 'age': 18}, {'name': 'tianqi', 'age': 77}]
年龄排序后 [{'name': 'tianqi', 'age': 77}, {'name': 'wangwu', 'age': 53}, {'name': 'zhangsan', 'age': 33}, {'name': 'zaoliu', 'age': 18}, {'name': 'lisi', 'age': 12}]
name排序后 [{'name': 'lisi', 'age': 12}, {'name': 'tianqi', 'age': 77}, {'name': 'wangwu', 'age': 53}, {'name': 'zaoliu', 'age': 18}, {'name': 'zhangsan', 'age': 33}]


实战练习

统计《三国演义》中人物的出场次数,并绘制出相关的词云图
大概思路
  • 准备工作:
    在pycharm终端中输入命令安装相应的包
    pip install jieba
    pip install collections
    pip install wordclude
    加载头文件
import jieba                                       #用来分词
from collections import Counter        #用来计算词语出现的次数
from wordclude import Worldclude   #用来生成词云分布图
  • 1.读入threekingdom.txt文本
    文件IO操作:https://www.runoob.com/python3/python3-file-io.html
  • 2.用结巴分词的.lcut()函数,将文本切割成一个一个的词语,存在一个集合words的数据结构里
  • 3.便历words 将每一个词和出现的次数对应存入字典counts{}中,每出现一次,对应词语的值+1
  • 4.用sorted()函数对字典的value(每个词出现的次数)为依据进行排序
  • 5.将具有相同人物属性的关键词元素进行合并
  • 6.去除类似"将军", "却说", "丞相", "二人", "不可", "荆州"这种与人物无关的字典元素
  • 7.调用wordclude包中的函数,生成相应的词云字符串
#案例
#三国小说人物出场词频统计
import jieba
from collections import Counter
import WordCloud




def parse():
    """ 三国小说人物出场词频统计 """
    #定义无关词集合
    excludes = {"将军", "却说", "丞相", "二人", "不可", "荆州", "不能", "如此", "商议",
                "如何", "主公", "军士", "军马", "左右", "次日", "引兵", "大喜", "天下",
                "东吴", "于是", "今日", "不敢", "魏兵", "陛下", "都督", "人马", "不知",
                '玄德曰', '孔明曰', '刘备', '关公'}
    with open('threekingdom.txt','r',encoding='utf-8') as f:
        txt=f.read()
    print(txt)

parse()


# # jieba分词
txt='我来到北京清华大学'
#讲字符串分割成等量的中文
seg_list=jieba.lcut(txt)
print(seg_list)

words=jieba.lcut(txt)
print(words)

counts={}
for word in words:
    if len(word)==1:
        continue
    else:
        #往字典里增加元素
        counts[word]=counts.get(word,0)+1 
 #第一次出现,先得创建一个键值对,key为word value=0
  print(counts)


  counts['孔明']=counts.get('孔明')+counts.get('孔明曰')
counts['玄德']=counts.get('玄德')+counts.get('刘备')
counts['关公']=counts.get('关公')+counts.get('云长')
  #删除字典中的无关词
  for word in excluds:
      del counts[word]

  #统计出现名字最高的前20个词
  items=list(counts.items())
  print(items)
  items.sort(key=lambda x:x[1],reverse=True)
  print("排序后:",items)

  for i in range(20):
      character,count= items[i]
      print(character, count)

#构造词云字符串
li=[]
for i in range(10):
    character, count = items[i]
    for _ in range(count):
        li.append(character)
print(li)

cloud_txt=','.join(li)
print(cloud_txt)


wc=WordCloud(
    background_color="white",
    font_path="msyh.ttc",
    #是否出现两个词的搭配  默认是True
    collocations=False
    ).generate(txt)
wc.to_file('三国词云.png')

To be continued......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343