当前位置: 首页 > news >正文

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__()方法。

转载于:https://www.cnblogs.com/Nicholas0707/p/8996959.html

相关文章:

  • Linux Memory Hotplug
  • 25个增强iOS应用程序性能的提示和技巧
  • 20165306 课下作业(第十周)
  • tortoise svn连接问题
  • 又一款基于BCH开发出来的社交软件BlockPress
  • 企业CIO如何做好免费ERP系统的选型
  • 【table】给table表格设置一个通用的css3样式(默认有斑马条纹)
  • 在Puppet中用ERB模板来自动配置Nginx虚拟主机
  • Linux下逻辑地址、线性地址、物理地址详细总结
  • 前端模拟数据生成器
  • cocos2dx 2.x 在ios8下clippingNode不起作用 解决办法
  • Docker 生态
  • Ant命令行操作
  • go 类型转换
  • c#运用TreeView控件的树形视图显示数据库中数据
  • JavaScript-如何实现克隆(clone)函数
  • #Java异常处理
  • chrome扩展demo1-小时钟
  • CSS居中完全指南——构建CSS居中决策树
  • CSS魔法堂:Absolute Positioning就这个样
  • Hibernate【inverse和cascade属性】知识要点
  • JavaScript 基础知识 - 入门篇(一)
  • maven工程打包jar以及java jar命令的classpath使用
  • Octave 入门
  • SpringCloud集成分布式事务LCN (一)
  • Travix是如何部署应用程序到Kubernetes上的
  • vuex 笔记整理
  • vue的全局变量和全局拦截请求器
  • 模型微调
  • 前端攻城师
  • 实现简单的正则表达式引擎
  • 我这样减少了26.5M Java内存!
  • 7行Python代码的人脸识别
  • Nginx实现动静分离
  • 通过调用文摘列表API获取文摘
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​你们这样子,耽误我的工作进度怎么办?
  • (2)MFC+openGL单文档框架glFrame
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (zt)最盛行的警世狂言(爆笑)
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)计算机毕业设计ssm基于B_S的汽车售后服务管理系统
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (三) diretfbrc详解
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (一)Dubbo快速入门、介绍、使用
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)linux下的时间函数使用
  • .cfg\.dat\.mak(持续补充)
  • .Net 4.0并行库实用性演练
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)