Python编程笔记(第三篇)【补充】三元运算、文件处理、检测文件编码、递归、斐波那契数列、名称空间、作用域、生成器
一、三元运算
三元运算又称三目运算,是对简单的条件语句的简写,如:
简单条件处理:
- if 条件成立:
- val = 1
- else:
- val = 2
改成三元运算
- val = 1 if 条件成立 else 2
二、智能检测文件编码
用第三方模块chardet
首先要安装chardet模块 ,用pip命令进行安装
chardet的用法
- import chardet
- f = open("staff_table.txt","rb")
- data =f.read()
- f.close()
- res = chardet.detect(data) #直接使用chardet模块中的detect方法
- print(res)
输出结果
- {'encoding': 'utf-8', 'confidence': 0.938125, 'language': ''}
分析:这里结果直接给出一个encoding是判断的结果,confidence是结果对的概率
三、模拟文件修改的方式
模拟修改文件中字符的方法
1、修改文件占硬盘,即在硬盘中修改
- import os
- f = open("test.txt","r+",encoding="utf-8")
- g = open("new_test.txt","w",encoding="utf-8")
- old_str = "的"
- new_str = "地"
- for line in f:
- if old_str in line:
- line = line.replace(old_str,new_str)
- g.write(line)
- f.close()
- g.close()
- os.replace("new_test.txt","test.txt") #注意在Windows平台不能直接重命名一个文件用os.replace()
- #或者
- #os.remove("test.txt") #注意在Windows平台不能直接用os.rename重命名一个文件为已经存在的文件的名字,必须先删除原文件
- #os.rename("newtest.txt","test.txt")
-
2、在内存中修改
- f = open("test.txt","r+",encoding="utf-8")
- data =f.read()
- data = data.replace("hello","xxxx")
- #由于f.read()读取文件将光标移动到文件内容的末尾,直接再次写入的会成追加模式
- f.seek(0) #需要重新将光标移动到开始,
- f.truncate() #由于修改后的字符串可能会比之前的字符串长度短,直接写入会有之前的字符在新写入的后面
- #这里需要用文件的truncate()方法对文件内容进行清空
- f.write(data)
- f.close()
四、修改文件名的方式
1、在mac\linux系统中,直接用os.rename()方法即可
- import os
- os.rename("new_test.txt","test.txt")
2、在windows系统中,不能直接用os.rename()方法,会报错,但是可以用os.replace()方法,效果与os.rename()方法一样
- import os
- os.replace("test.txt","new_test.txt")
五、可变参数组
1、*args用作传递非命名键值可变长参数列表(位置参数),之后不要加普通的参数
- def send_msg(msg,*args,age):
- print("信息是",msg,args,age)
-
- send_msg("你好,我的信息是",*["nicholas","male"],22)
这样写会报错,错误提示“age”缺少一个参数,因为*args会接收实参里的22,造成age没有参数。
这样写可以
- def send_msg(msg,*args,age):
- print("信息是",msg,args,age)
-
- send_msg("你好,我的信息是",*["nicholas","male"],age=22)
这样写不会报错,但是一般写程序不会这样写。
五、尾递归优化
递归过程中,假如说求1000!的阶乘,会出现栈溢出的问题,因为在函数执行中,每次调用一个函数都会把当前函数的调用位置和内部变量保存在栈里面,由于栈的空间不是无限大(python一般为1000层深度),假如说调用层数过多,就是出现栈溢出的情况。
这个时候就可以用尾递归优化来解决,尾调用的概念非常简单,一句话就能说清楚,就是指递归函数函数的最后一步是调用这个函数本身。
例子
- def jc(n):
- print(n)
- return jc(n +1)
- jc(1)
尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用记录,因为调用位置、内部变量等信息都不会再用到了。所以尾递归优化可以有效的防止栈溢出,但是尾递归优化需要编译器或者解释器的支持,但是大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,C语言针对尾递归做了优化,做完优化和for循环执行一样,但是python没做优化,所以即使把上面的jc()函数是尾递归方式,也会出现栈溢出。
六、eval()、exec()
eval可以执行字符串形式的表达式,并返回计算结果。
例子
- print(eval("1+2+3"))
输出结果
- 6
exec()函数将字符串str当成有效的Python表达式来执行,不返回计算结果
- exec('print("hello world !")')
输出结果
- hello world !
这里的内外层双引号不能相同,否则会报错
例子
- code = '''
- def func():
- print('你好')
- return 'nicholas'
- v = func()
- print(v)
- '''
- exec(code)
输出结果
- 你好
- nicholas
例子
- code = '''
- def func():
- print('你好')
- return 'nicholas'
- v = func()
- print(v)
- '''
- res = exec(code)
- print(res)
输出结果
- 你好
- nicholas
- None
exec()不返回计算结果。
七、callable()
判断一个东西是否可调用,可被调用指的是对象能否使用()括号的方法调用。
例子
- li = [1,2,3]
- print(callable(li))
输出结果
- False
例子2
- def func():
- print("hello")
- print(callable(func))
输出结果
- True
八、递归练习
题目
如何猜数字,猜0到100中间的一个数字,写出猜出的过程。
用二分法和递归来写
- li = [i for i in range(100)]
- def search(num,data):
- num_max = len(data)
- num_mid = int(( num_max) / 2)
- if num > data[num_mid]:
- print("smaller")
- print("列表的首位是%s,末尾是%s"%(data[0],data[-1]))
- return search(num,data[num_mid:])
- elif num < data[num_mid]:
- print("bigger")
- print("列表的首位是%s,末尾是%s" % (data[0], data[-1]))
- return search(num,data[:num_mid])
- else:
- print("find it")
- search(88,li)
九、名称空间
又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方
名称空间共3种,分别如下
locals: 是函数内的名称空间,包括局部变量和形参
globals: 全局变量,打印这个程序所有的变量
builtins: 内置模块的名字空间
不同变量的作用域不同就是由这个变量所在的命名空间决定的,有了名称空间才有了作用域
作用域即范围
全局范围:全局存活,全局有效
局部范围:临时存活,局部有效
查看作用域方法 globals(),locals()
十、作用域的查找顺序
LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> builtins
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间
十一、列表生成式+三元运算
列表生成式和三元运算可以混合使用
例子
- li = [i if i < 3 else i*i for i in range(6)]
- print(li)
输出结果
- [0, 1, 2, 9, 16, 25]
例子
- li = [i if i != "a" else i*2 for i in "nicholas"]
- print(li)
输出结果
- ['n', 'i', 'c', 'h', 'o', 'l', 'aa', 's']
分析:这里的for i in var ,var可以是字典、列表,也可以是字符串
十二、用两种方法来写斐波那契数列
求第n个斐波那契数列元素是多少
方法一:递归
- def fib(n):
- if n == 0 or n == 1:
- return n
- else:
- return fib(n-1)+fib(n-2)
- print(fib(10))
方法二:循环的方法
- def fib2(n):
- a,b=0,1
- count = 1
- while count < n:
- a,b = b,a+b
- count = count + 1
- return b
- print(fib2(10))
十三、isinstance()
可以使用isinstance()判断一个对象是否是Iterator对象(迭代器)或者Iterable是否可迭代(可迭代对象):
例子
- from collections import Iterable
- li2 = (i for i in range(10)) #生成器表达式
- dic = {"k1":"v1"}
- li = [1,2,3]
- s = "nicholas"
- n = 2
- print(isinstance(li2,Iterable))
- print(isinstance(dic,Iterable))
- print(isinstance(li,Iterable))
- print(isinstance(s,Iterable))
- print(isinstance(n,Iterable))
输出结果
- True
- True
- True
- True
- False
分析:字典、列表、字符串都是可迭代对象,这里的生成器就是迭代器,
迭代器一定是可迭代对象,可迭代对象不一定是迭代器,如这里的字典、列表等需要用__iter__()
方法才能变成迭代器。
例子2
- from collections import Iterator
- li2 = (i for i in range(10)) #生成器表达式
- dic = {"k1":"v1"}
- li = [1,2,3]
- s = "nicholas"
- n = 2
- print(isinstance(li2,Iterator))
- print(isinstance(dic,Iterator))
- print(isinstance(li,Iterator))
- print(isinstance(s,Iterator))
- print(isinstance(n,Iterator))
输出结果
- True
- False
- False
- False
- False
分析:这里只有生成器表达式才是迭代器,既包含__iter__()
方法又包含__next__()
方法。
Python编程笔记(第三篇)【补充】三元运算、文件处理、检测文件编码、递归、斐波那契数列、名称空间、作用域、生成器的更多相关文章
- Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- 斐波那契数列的三种C++实现及时间复杂度分析
本文介绍了斐波那契数列的三种C++实现并详细地分析了时间复杂度. 斐波那契数列定义:F(1)=1, F(2)=1, F(n)=F(n-1) + F(n-2) (n>2) 如何计算斐波那契数 F( ...
- 斐波那契数列-java编程:三种方法实现斐波那契数列
题目要求:编写程序在控制台输出斐波那契数列前20项,每输出5个数换行 斐波那契数列指的是这样一个数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, … 这个数列 ...
- python实现斐波那契数列笔记
斐波那契数列即著名的兔子数列:1.1.2.3.5.8.13.21.34.…… 数列特点:该数列从第三项开始,每个数的值为其前两个数之和,用python实现起来很简单: a=0 b=1 while b ...
- python学习笔记之斐波拉契数列学习
著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到: 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 如果用Python的列表生成式, ...
- Python练习笔记——斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一 ...
- 用递归方法计算斐波那契数列(Recursion Fibonacci Sequence Python)
先科普一下什么叫斐波那契数列,以下内容摘自百度百科: 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因意大利数学家列昂纳多·斐波那契(Leonardoda Fibonacci ...
- Python 实现 动态规划 /斐波那契数列
1.斐波那契数列 斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数 ...
- python实现斐波那契数列
https://www.cnblogs.com/wolfshining/p/7662453.html 斐波那契数列即著名的兔子数列:1.1.2.3.5.8.13.21.34.…… 数列特点:该数列从第 ...
随机推荐
- 1.3.3、CDH 搭建Hadoop在安装之前(端口---CDH组件使用的端口)
列出的所有端口都是TCP. 在下表中,每个端口的“ 访问要求”列通常是“内部”或“外部”.在此上下文中,“内部”表示端口仅用于组件之间的通信; “外部”表示该端口可用于内部或外部通信. Compone ...
- cakephp 利用Pushapi扩展 进行app 消息推送
public function push_designer_app($params) { $this->layout = false; $this->autoRender = false; ...
- 苹果笔记本 如何配置成php开发系统
方法一 启动内置的apace 打开终端输入命令 停止服务:sudo /usr/sbin/apachectl stop 开启服务:sudo /usr/sbin/apachectl start 重启服务: ...
- 深入理解 mysql 索引
1.资源准备 FQ软件下载:蓝灯 2.红黑树模拟:https://www.cs.usfca.edu/~galles/visualization/RedBlack.html 3.B树模拟:https:/ ...
- Linux 永久PATH环境变量
在/etc/profile文件中添加变量[对所有用户生效(永久的)] 用vim在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”. 例如:编辑/etc ...
- 第三章 列表(b)无序列表
- CentOS ./configure && make && make install详解
码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install). 在Linux中利用源码包安装软件最重要的就是要仔细阅读安装包当中的README INST ...
- SVN集成compare4比较软件
打开TortoiseSVN的Setting,选择左边的Diff Viewer 设置如下: "D:\Program Files\Beyond Compare 4\BComp.exe" ...
- Angular之输入输出属性
一 父组件 company.component.ts import { Component, OnInit } from '@angular/core'; @Component({ selector: ...
- stm32中adc的常规通道和注入通道的区别
STM32的每个ADC模块通过内部的模拟多路开关,可以切换到不同的输入通道并进行转换.STM32特别地加入了多种成组转换的模式,可以由程序设置好之后,对多个模拟通道自动地进行逐个地采样转换. 有2种划 ...