python入门基础-杂记

编程的初识

1.什么是编程语言?

学编程 == 学语法规则

编程能干什么?

一堆指令的组合 ==> 软件

操作系统的位数:

​ 32bit = 内存的最大寻址空间是2^32^,

​ 64bit = 内存的最大寻址空间是2^64^,实际上也并不是完全的64位又部分保留实际上应该是2^40^~2^50^左右。

​ 目前主板支持的最大内存为16T大概是2^44^=16T,所以64bit是未来必须的。

​ 4GB的内存使用32位的系统和64位的系统哪一个比较快呢?

答:理论上是一样的

图文介绍:

2.编程主流语言的介绍

①C(1973诞生很底层的语言)是现阶段的语言的基石!

​ c++(1983年诞生贝尔实验室) = c语言的加强版

②java (1995年诞生由San公司开发出来)

③php(1994,纯Web开发语言)Netscape浏览器诞生

④python(1989年诞生)

​ 跟linux同年诞生,1991年正式版

​ 刚开始被作为脚本语言,用他来写一些小任务

⑤c#=c sharpe(微软开发)

⑥ruby(20世纪90年代日本人开发95年发布)和python有点像

​ ruby on rails web 框架

⑦perl(诞生于Unix平台)

​ 十分强大的文字处理能力,可以写出没人能看懂的代码(不温不火)

⑧shell(脚本语言)

​ 简单易学,基于unix/linux做一些简单的系统管理任务,运维人源必须学的。

⑨scalar(大数据语言)

​ 是一种多范式编程语言,一种类似Java的语言。

⑩erlang(20世纪80年代)

​ 一种函数编程语言,来自电信设备制造商爱立信开发。

⑪go语言(2009年谷歌开发!

​ 针对多处理系统应用程序的编程语言。

⑫Javascript(主要写前端的语言!

​ 是当下使用最多的语言了

​ nodejs写后端 全栈式的语言

⑬VB(微软开发)

​ BAT批处理

⑭lua(nginx脚本语言)

​ nginx是时下最NB 的WEB服务器

3.python的初识

python(蟒蛇)的创始人为吉多.范罗苏姆(Guido van Rossum)为了打发时间,决定开发一种脚本解释程序。

目前python主要的应用领域

  • -云计算
  • -Web开发
  • -科学运算
  • -系统运维
  • -金融

Python是什么样的语言?

编译型 = 全部编译再执行

解释型 = 边执行边编译

  • 计算机中,一切皆对象
  • 世界万物,皆对象
  • 世界万物,一切对象皆可分类

Python的历史

  • python 2.6 – October 1 ,2008

  • python 2.6.1 – October 1 ,2008-现在

    • python 2.7 – July 3 ,2010 #目前的业内主流使用的工业版本依然是2.7
  • python 3.0 – December 3 ,2008 #3.0和2.X同时发布改写了不少的2.X存在的问题,但是对于大型的公司影响很大,因为不兼容所以推出2.X.X来逐渐的修改。

*in November 2014,IT was that 2.7 would be supported until 2020.不再支持2.8了必须迁移成为3.4以上的才行!

例子:(语法改动)

​ print “Hello word” # 2.X是遗产(legacy)不支持中文(默认编码ASSIC)

​ print (“Hello word”) # 3.0是未来(future)默认支持中文(默认编码UNICODE)

python 2 VS 3:

  1. 默认不兼容中文
  2. 不兼容2.X
  3. 核心语法调整更容易学习
  4. 新特性默认只在3.X上有
  5. 在2.X上写的代表需要声明需要使用的字符编码,在3.X就不需要声明。

pycharm介绍

  • 集成开发环境(IDE,Integrated Development Environment)
  • VIM –> 经典的linux下的文本编辑器
  • Emacs –> linux的文本编辑器,比VIM更容易使用
  • Eclipse –> Java IDE,支持 python c c++
  • Visual Studio –> 微软开发的IDE ,支持 python c++ java c#
  • notepad++
  • sublime python 开发的

pycharm,是主要用于Python开发的IDE

ctrl + ? ——- 选中的直接注释

Python基础语法

变量:是为了存储程序运算过程中一些中间结果的。为了方便日后调用。

常量:不变的量(π,算数公式),在Python中用全大写变量名来代表常量。

变量的命名规则:

  1. 要具有可描述性
  2. 变量名只能_,数字,字母组成,不可用空格或特殊字符(!@#¥%…&)
  3. 不能以中文为变量名称
  4. 不能以数字开头
  5. 保留字符是不能被使用的(print系统保留的不能)

注释

–》单行注释 #

–》多行注释 ‘’‘要注释的’‘’或者“”“”要注释“”“”

缩进的限制

python代码缩进级别必须保持一致,肉眼上一个TAB=4个空格,但是在实际意义上不同的。

但是官方的建议不要直接使用TAB,因为Windows和linux上的TAB 不同。换平台会导致代码错误。

例如在notepad++上设置4个空格=1个Tab:

内存如何释放的呢?

Python很好的就是会自动给你释放内存不用像其他的编程语言需要主动的释放内存。

##1.关于字符编码的认识

ASCII最后预留下了128位给除了美国欧洲以外其他国家使用,但是对于中文来说远远不够。

聪明的中国人想到了,设置新的拓展表【GB2312】,每当机器遇见了中文就去从拓展表中查询。【GB2312】1980年第一版,但是还是无法满足需要。2000年直到现在的【GB18030】支持藏文、蒙文。

因为世界上国家众多语言众多,所以为了统一,出现了万国编码称为:【unicode】支持世界所有国家地区的编码且向下兼容中文的GBK类型编码。2^16^ = 65535 存储一个字符,统一占用2个字符而ASCII码占用1个字符。但是2字符过大涉及到了存储问题。

所以UTF-8 = unicode诞生了,UTF-8是unicode的扩展集,不再使用统一的最小2字符,而进行了详细的分类ASCII码中的字符依然是1个字符,中文变成3个字符。UTF-8才是真正在世界上广泛使用的编码。

编码在实际的操作中的运用

  • Windos -> 默认的编码是GBK,默认可以支持uinicode and gbk

  • python2 -> 在Windos上解码是必须的,编码成GBK这个动作不是必须的

  • python2 -> 在linux上,如果是GBK -> utf-8,解码是必须的,编码成UTF8这个动作不是必须的所有的程序在内存里面默认都是unicode类型

  • python3 -> 默认文件是utf-8,解释器编码是unicode,文文件加载到内存后会自动解码unicode,同时也把字符串转化成bytes格式

pyton2和python3编码的区别

  • python2 str == python3 bytes

  • python3str == unicode

  • python3 多出来的那个bytes格式是一个单独的数据类型

演变的历史:

ASCII –> GB2312 –> GBk1.0 –> GB18030 【中文编码的演变】

ASCII –> unicode –> UTF-8 / UTF-16 【世界编码的演变】

二进制

–> ASCII:只能存英文和拉丁字符,一个字符占用一个字节,8位

—–> GB2312;只能6700多个中文,1980年

———> GBK1.0:存了2万多字符, 1995年

————–> GB18030:27000个中文字符,2000年

unicode的演变史

———–》Unicode:utf-32:一个字符占4个字节

———–》unicode:utf-16:一个字符占2个以上,65535

———–》Unicode:utf-8;一个字符用ASCII码来存储一个中文占3字节

  • 在python 2中的编码:默认为ASCII!
  • 在python3中的编码:默认为Unicode
    ##当python2.7和python3.6的碰撞##

##2.数据类型结构

  • 整型【int】

    python中输入:

    print(type(123456))。输出的结果为整数

  • 浮点型【float】

    python中输入:

    print(type(123456*9999999999999999999999915))。输出的结果为整数

  • 复数【complex开发中很少用】

    2+3j复数虚部结尾一般以大J 或者 j 来结尾

  • 布尔型【bool】

    Ture(非零或非空)=真/False(0)

    布尔值可以做运算的!在运算中Ture=1 False=0

    例如:Ture+Ture=2

  • 字符串【str】

    input:接受所有的数据都是字符串,即便你输入的的数字,但是依然会被当成字符串来处理。

在Python3中,进行运算之后的结果,首先默认会向复杂的结果靠拢

在Python3中,触发的结果会自动向浮点数靠拢

字符串的拼接:

print(“abc”,”sdf”) >>>abc sdf

print(“abc”+”sdf”) >>>abcsdf

  • 集合 【set】(可变集合、不可变集合)

定义:集合是一个无序的,不重复的数据组合。

作用:①去重 –> 将一个列表变成集合,自动去重

​ ②关系测试 –> 测试两组数据之前的交集、差集、并集等关系!

  1. 集合的创建

s1=set(‘内容’) 或者 s2=frozenset(‘内容’)

  1. 集合的访问

集合本身是无序的,所有不能为集合创建索引或切片操作,只能遍历或使用in、not in来访问判断集合元素。

a=[‘a’,1,2,’3′,1]

s=set(a)

print(‘a’ in s) #返回Ture 或 False

  1. 集合的更新

增(add)、删(del、pop、remove)、改(update)、查

add和update区别:只添加一个且是整体,update分开

  1. 集合类型操作符
  • in、not in
  • 集合等价与不等价(==,!=)
  • 子集(<)、超集(>)
  • 交集(&)、并集(|)、差集(-)、对称差集(^)

3.python的运算符

赋值运算:

(= 、+= 、-=、 *=、 /=、 %=、 //=、 **=)

比较运算符:

( <、>、 >=、 <=、 ==、!= True False )

简单的说就是用来做比较的,比较的结果为两种成立True,不成立为False

逻辑运算符:

  • not 不
  • and 并且
  • or 或

成员运算符:

介绍:用来判断一个元素是否是另外的一个元素成员,得到的结果只能为True或者False。

  • not in
  • in

身份运算符:

介绍:经常用来判断变量的数据类型。

  • is
  • is not

解释:程序运行在内存中,计算机在给a赋值为123456的时候,其实是在内存中开辟了一段内存空间为(X1),将a=b的时候实际上是吧b的地址指向了X1,然而,c的值虽然也是123456,但是实际上是在一段新的空间开辟出的值为X2。c的值指向X2,所以看上去c和a的值是相等的,但是计算机认为内存地址不是同一个所以给出了False。

优先级:

4.在window交互界面的运用

python的交互界面:

​ 开始 –> cmd –> python进入交互界面

​ 本地桌面新建一个文件:python.py 编辑–> print(“Hello Word”)

在交互界面中:

​ CD = change dirctory cd .. 返回上层目录 cd../返回上上层目录

​ dir = 查看当前目录下文件相当于linux-》ls

所以:

​ cd c:\Users\hasee\Desktop –> dir –> c:\Users\hasee\Desktop\python.py –> hello word 或 python c:\Users\hasee\Desktop\python.py #设置环境变量

5.字符格式化输出

占位符:

  • %s s = string 字符串
    • %dd = digit 整数
  • %f f = float 浮点数,约等于小数

6.列表和元祖

如果你要存储一系列的人名或者书籍名称,基础思维就是使用变量进行存储,但是很麻烦单一所以,开发出了列表。

列表定义初始化

  • list -> new empty list

  • list(iterable) -> new list initialized from iterable’s items

  • 列表不能一开始就定义大小

定义方式:
lt = list()
lt = []
lt = [3,1,'aq']
it = list[range(5)]

列表索引访问

  • 索引也称为下角标

  • 正索引:从左到右,从0开始为列表中每一个元素标号

  • 负索引:从右到左,-1开始

  • 正负索引不可以超界,否则引发异常IndexError

列表通过索引来访问: list[index],index就是索引,使用中括号访问

  • 列表存储格式

a=[‘ddy’,’ccy’,’xiaoxin’,’qifei’,’666′] #对于列表的操作增删改查

  • 列表的操作
  1. 查 切片

特点 ←左包括 →右不包括|【a : b : c】–》a左,b右,c间隔取一次

print(a[1:]) #取值到最后

print(a[1:-1]) #取值到倒数第二个值,正左开始,负又开始

print(a[1: -1 :1]) #从左到右一个一个去取值

  1. 添加 append insert

a.append(‘内容’) #默认加在最后

a.insert(位置,’内容’) #不填写位置默认最后

  1. 修改

比如修改一项:a[1]=’666′

比如修改多项:a[1:4]=[‘a’,’b’]

当你取出来的时候是多个就是一个列表,所以需要用一个列表来承载修改

  1. 删除 remove pop del

①a.remove(a[内容]) #remove只支持删除内存不允许索引

②a.pop(索引) #pop删除后有返回值–》b=a.pop(1) –》print(b)

③del a[索引] or del a #可以删除整个列表对象也可以删除某一项

④a.clear #清空只剩余一个中括号了

  1. 其他操作

统计 a.count(‘内容’)

扩展 a.extend(对象)

查找 a.index(”内容”)

当列表中存在多个相同的项时候,index默认只取出从左开始的第一个,无法取出后面的几个,如果想要取到后面的几个相同项的位置的时候就必须,利用切片后取出!

显示结果:

翻转 a.reverse()

排序 a.sort

从大到小依次排序,也可以进行字母进行排序(但是字母根据ASCII码)

列表的算法比较

  • 求100以内的素数,比较两种写法的效率差距

元祖

介绍:元祖被称为只读列表,数据只可被查询,单不能被修改,所以列表的切片同样适用元祖。

列表:[]

元祖:() 一旦被创建就无法修改

定义初始化

tuple() -> empty tuple

tuple(iterable) -> tuple initialize

元素的访问

  • 支持索引(下角标)

  • 正索引 -> 0 、 负索引 -> -1

元祖的语法

a=(1,2,3,4)

a.cont 统计

a.index 查询

元祖查询

  • index(value,[start,[stop]])
    • 通过值value,从指定的区间查找列表内的元素是否匹配

    • 匹配第一个就立刻返回索引

    • 匹配不到,抛出异常ValueError

  • count(value)

    • 返回列表中匹配value的次数
  • 时间复杂度
    • index和count方法都是On

    • 随着列表数据规模的变大,而效率降低

  • len(tuple)

    • 返回元素的个数
  • 关于深浅拷贝

深拷贝和浅拷贝,python中一切皆对象,像数字、字符串、元祖,如果在内存中存储了这些元素,那么这块内存中的值是不可被修改的,但是还存在一些可变的对象,比如列表和字典,他们所占有的内存空间是可以修改的,有因为python中使用的是引用计数去节省内存。

浅拷贝

当你使用切片操作拷贝的时候,虽然我们可以修改外层列表,而且不影响其他列表,但是内层的子列表被修改的时候,一样受到了影响。

浅拷贝的方式:切片或copy

实际情况中的运用

7.字典Dictionary

介绍:字典是python中唯一的映射类型,采用键值对(key-value)的实现存储数据,python对key进行哈希函数运算,根据计算的结果决定value存储的地址,所以字典是无序存储的,且KEY必须是可哈希的,可哈希便是KEY必须是不可变类型,如:数字、字符串、元祖。

  • 不可变类型:整数、字符串、元祖
  • 可变类型:列表、字典
  • 字典特点:无序性、键值唯一

创建dic字典的两种方法:

2种创建字典的方式:

  1. 增加

  1. 查找

字典的不同就在于字典是不存在索引,只能以键值为查询目标。

print(dic[‘name’]) #这是打印name的值

  1. 修改

  1. 删除
  • del dic #删除字典
    • dic.clear() #清除字典,但是这个时候的dic可以做为对象
  • dic.pop(‘键’) #删除键值且返回你删除的键值可以变量接收

如果pop不加键随机删除一个键值

  1. 字典的嵌套

  1. 排序

  1. 字典的遍历

dic={‘name’:’ddy’,’age’:19}

for i in dic:

​ print(i,dic[i])

8.字符串的认识与深入

  • 一个字符组成的有序的序列,是字符的集合

  • 字符串是不可变的对象

  • 初步的认识字符串

  • 深入了解字符串

9.python的文件操作

文件系统的基本操作

open(‘文件名’,’打开方式’,encoding=”打开格式”) #打开文件file.close() #关闭文件


打开文件的模式有:

  • r –> 只读写模式(默认)
  • w –> 只写模式【不可同时进行读写,不存在则创建,存在则删除内容】
  • a –> 追加模式 【可读,不存在则创建,存在则只追加内容】

”+“号表示可以同时读写某个文件

  • r+ –> 可读写文件(默认)
  • w+ –> 写读
  • a+ –> 追加同上的a

“U”表示在读取时,可以将\r,\n,\r\n自动替换成\n(与r或r+模式同时用)

  • rU
  • r+U

“b”表示处理二进制文件(如:FTP上传ISO镜像文件,window处理二进制文件要标注)

  • rb
  • wb
  • ab

多行读取打印的分析


拓展:with用法

存在的意义:为了避免打开文件后忘记关闭,可以通过管理上下文:

date=open(‘文件名’,’r’,encoding=’uft-8′)

……..

date.close()

with open(‘文件名’,’w’) as date , open(‘文件名’,’r+’,encoding=’uft-8′) as a:

pass

两者之间没有区别,with更加方便不会忘记close,而且可以多行打开。

10.python的函数

计算机函数(function) = subroutine 子程序 ,procedures 过程

def –》define (定义)

作用

  1. 减少重复代码
  2. 方便修改,更容易拓展
  3. 保持代码的一致性

定义

函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需要调用函数名即可。

函数的命名规则

  • 函数名必须以下划线或字母开头,可以包含任意字母,数字或下划线的组合不能使用任何的标点符号。
  • 函数名是区分大小写的。
  • 函数名不能是保留字。

函数的形参和实参

形参:不是实际存在的,是虚拟变量,在定义韩寒和函数体的时候使用形参,目的是在函数调用中起到传递参数给内部使用的作用。

实参:实际的参数,调用函数是传递给函数的参数,可以为变量,表达式,函数,传给行参。

区别:形参是虚拟的,不占用内存,只在被调用的时候才分配内存单元,实参单向传递给形参。

函数的参数类型

  • 必备参数
  • 关键字参数
  • 默认参数
  • 不定长参数

必备参数

关键字参数


默认参数

不定长参数与(*args、**kwargs)

  • *args接收的不定长参数放在元祖中 (1,2,3,’ddy’)

  • **kwargs接收的不定长参数放在字典中 {‘name’:’ddy’,’age’:21,’sex’:’male’}

函数的返回值

def function()

return 自定义对象 #作用:1.结束函数 2.返回某个对象

特点:

  • 函数如果没有return,会默认返回一个none
  • 如果return多个对象,那么python会帮助我们把多个对象封装成一个元祖返回

函数的作用域

  • B:built-in,系统固定模块里面的变量
  • G:global,全局变量模块级别的变量
  • E:enclosing,嵌套的父级函数的局部作用域
  • L:local,局部作用域函数中的定义变量

搜素变量的优先级为:

局部>外层>当前模块中的全局>系统内置

简写:—> L>E>G>B

需要注意的点和变量的声明

递归函数

递归的特性:

  • 调用自身函数
  • 必须有一个结束条件
  • 某些时候递归会导致拖累程序运行速度,前提在不影响程序本身的时候
  • 递归常规速度慢,递归能解决的循环都可以解决
  • 递归的效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减少一层栈帧,由于栈的大小不是无限的所以,递归调用的次数过多,会导致栈溢出)


递归函数的实际运用

  • 二分法查找

斐波拉契数列

编写程序实现:输入任意的数,输出对应的值

特性:改数列后一个数的值等于前两个数的值之和。

—>> 0 1 1 2 3 5 8 13 <<—

位置–>> 0 1 2 3 4 5 6 7

分析:

①递归函数(逆向思维)

前提->当你取位置为3的数的时候,结果为前2位数之和

函数表达式:f(2)+f(1) –> f(0)+f(1)+f(1)

衍生出表达式:f(n-1)+f(n-2) # n为需要输出的数的位置

②常规循环

前提:既然结果为前两个数之和所以,用for循环累加,条件为n-1次

表达式:前一次+前两次=一个值

​ 0位置时候为值0,1位置为值为1

​ for循环次数n-1

系统内置函数

开发中常用的内置函数

基础常用:filter、map、reduce、lambda

  • filter(func,seq) –>过滤器

解释:func函数,seq序列,将func函数应用到seq序列的每一个元素中,并返回一个新的序列。

是已知的序列的每个元素调用给定的布尔函数,在调用中,返回值为非零值的元素将被添加至一个列表中。

  • map(func,seq) –>映射器

解释:将函数func作用于给定序列seq()的每一个元素,并用一个列表来提供返回值,如果func为None,func表现为一个身份函数,返回一个含有每个序列中元素集合的N个元祖的列表。

同样的写法在Py3.5就报错,解决办法list(内容)

  • reduce(fucn,seq[,init]) –>折叠器

解释:func为二元函数作用于seq序列的元素,前一个元素和后一个元素的值跟下一个元素相加,最后减少我们的序列为一个单一的返回值(实现阶乘或者求列表中所有元素的和)

  • lambda –> 创建匿名函数

解释:因为lamdba在创建时不需要命名,所以叫匿名函数。  

结构 —> lambd a,b : a+b(:号左侧接受的形参,右侧返回的值)

匿名函数的限制 –> 最为复杂的运算就是三元运算了

为什么要使用函数之模块化程序设计?

不使用模块化程序设计的缺点:
    1.体系结构不清晰,可持续差
    2.可扩展性
    3.程序荣昌

高阶函数

  • 函数名可以作为参数输入
  • 函数名可以作为返回值

函数的嵌套

  • 函数调用

  • 函数定义

嵌套最多为2-3层,多了可读性很差

闭包函数

11.Python的装饰器

  • 主要使用地方

    对已经上线过的代码进行修改,需要遵循的原则为:

    1.一定不能修改源代码
    
    2.不能修改调用的方式
    

装饰器相当于在原函数上给予一个新的修饰,装饰器本身是一个可调用的对象

  • 装饰器的三要素:

作用域 –> 高阶函数 –> 闭包

  • 装饰器(一)

  • 装饰器(二)

  • 装饰器小知识点


python的判断循环语句实战

判断语句:

  • if
  • elif 方便快捷不用多次写else
  • else

循环语句:

while 条件:(中文意思:当)

….

else:(continue时候执行,除非程序错误或者break时候不执行)


嵌套的while循环:

有限循环:

for 条件 : 例子:for i in 序列 【序列中必须有元素】

​ ….

else :

​ ….


list=[‘1’,(1,2),[‘dd’,’qw’,1],23,54]

for i in enumerate(list)

项目实战:输出三角形

设计输出一个三角形用*代替星星。

  • 思维导图
  • 分析公式
  • 书写代码



代码区:

项目实战:九九算数表

项目实战:信息表

冒泡排序

  • 属于交换排序

  • 两两比较大小交换位置,如同水泡向上冒

  • 结果分为升序和降序

升序:n个数从左到右,编号从0开始到N-1,索引0和1的值比较如果索引0大,则交换两者的位置,如果索引1大则不需要交换。继续比较索引1和2的值,将大的值放在右边,直到N-2和N-1比较结束。第一轮结束后,开始第二轮从索引0比较大索引N-2,因为最右侧位置上已经为最大值,以此类推每一轮都会刷新右侧信息直到最后两个值比较大小

冒泡法代码的实现(不考虑性能条件下):
c = []
gg =int(input('请输入你要排序的次数:'))
for a in range(gg):
    c.append(int(input('当前输入的次数{}:'.format(a))))

num_list = [
[1,2,231,123,435,234,8,130,0]
]
num_list.append(c)

nums = num_list[1]
print(nums)
length = len(nums)
count_swap = 0
count = 0

for i in range(length):
    for j in range(length-i-1):
        count += 1
        if nums[j] > nums[j+1]:
            tmp = nums[j]
            nums[j] = nums[j+1]
            nums[j+1] = tmp
            count_swap += 1
print(nums,"最终交换的次数:",count_swap,"循环了多少轮:",count)


考虑性能的条件下:
c = []
gg =int(input('请输入你要排序的次数:'))
for a in range(gg):
    c.append(int(input('当前输入的次数{}:'.format(a))))

num_list = [
[1,2,231,123,435,234,8,130,0]
]
num_list.append(c)

nums = num_list[1]
print(nums)
length = len(nums)
count_swap = 0
count = 0
for i in range(length):
    flag = False
    for j in range(length-i-1):
        count += 1
        if nums[j] > nums[j+1]:
            tmp = nums[j]
            nums[j] = nums[j+1]
            nums[j+1] = tmp
            count_swap += 1
            flag = True
    if not flag:
        break
print(nums,"最终交换的次数:",count_swap,"循环了多少轮:",count)

总结

  • 冒泡法需要数据一轮轮的比较大小

  • 可设定一个标记判断次轮是否有数据发生交换,如果没有发生交换可以结束排序,如果有交换则继续下去

  • 最差的排序情况:初始化顺序与目标顺序完全相反,遍历次数1 <-> n-1之间和n(n-1)/2

  • 最好的排序情况:初始化顺序与目标顺序完全相同,遍历次数n-1

  • 时间复杂度O(n²)

Python的模块

  • 什么是模块?

    一个模块包含了了Python定义和声明的文件,文件名就是模块名字加上.py的后缀

  • 为何要使用模块?

    如果你退出Python解释器然后重新进入,那么你之前定义的函数或者变量都将会丢失,因此我们通常将程序写入到文件中以便永久的保存下来,需要时候就通过python test.py方式去执行,此时的test.python被称为脚本。

    随着时间的发展,功能的越来越多,我们通常将程序分割为一个个的小文件,可以把它们作为模块导入到其他的模块中,实现功能重复利用。

  • 如何使用模块

    第一次导入模块做了三件事情
        1.创建新的作用域
        2.在该作用域内执行顶级代码
        3.得到一个模块名,绑定到该模块内的代码
    
  • 1 -> import 模块名

  • 2 -> from 模块名 import 模块内函数

    两者使用的区别:

    (import 模块名)使用的时候必须使用函数名。模块名.xxx()
    (from 模块名 import)不需要模块名.xxx()就能调用。
    #但是问题就出现了,而二不带作用域,如果和当前的定义有名字相同的会产生冲突。
    
  • 什么是Python之禅

1.优美胜于丑陋(Python 以编写优美的代码为目标)
2.明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
3.简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
4.复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
5.扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
6.间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
7.可读性很重要(优美的代码是可读的)
8.即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)
9.不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写 except:pass 风格的代码)
10.当存在多种可能,不要尝试去猜测
11.而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
12.虽然这并不容易,因为你不是 Python 之父(这里的 Dutch 是指 Guido )
13.做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
14.如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
15.命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)
  • 模块也支持别名
    form time import time.time as a
    
  • 模块还支持多行导入
    from time import (xxx,xxx,xxx)
    
  • 总结:从哪里来就从哪里执行,与调用的位置无关系
    from modules import *   #把模块中所有的不是以下划线开头的函数取出
    
  • python不支持模块重载
    假如当你的模块改名了,程序是无法感知到的,因为程序默认读取的是在内存中已经加载的模块而不读刚修改完的模块。
    所以如果想要实现读取修改好的模块,需要重启你的程序。
    
  • 模块的搜索路径
    模块的查找顺序是:内存中已经加载的模块->内置模 块->sys.path路径中包含的模块
    

Python什么是包

  • 包是一种通过使用(.模块名)来组织Python模块空间的方式
    简单来说:包就是一个directory,一个包含有___init__.py文件的文件夹,所以其实我们创建包的目的就是为了用文件夹/模块组织起来。
    重点:
    Python2和Python3中包的区别为
        1.在Python3中,即使包下没有___init__.py文件,import包依然不会报错,但是Python2中,包一定要有文件,否则import包会报错。
        2.创建包的目的不会为了运行,而是被导入。包只是模块的一种形式而已,包的本质就是一种模块。
    
  • init.py文件到底是什么?
    不管是哪一种方式,只要是第一次导入包或者是包的任何其他部分,都会依次执行包init文件。所谓的导入包就是执行包下面的init文件。
    

  • 重点
    注意:
        可以用import导入内置或者是第三方模块,但是要绝对避免使用import来导入自定义的包的子模块,应该使用(from import )的绝对或者相对导入,而且包的相对导入只能用from的形式。
    
  • 绝对导入和相对导入,也就是Linux中的绝对路径和相对路径

  • 单独导入包

Python列表生成式,迭代器,生成器

  • 什么是列表生成式

  • 生成器
    通过列表生成方式,我们可以直接常见一个列表,但是,受到内存的限制,列表的容量肯定是有限制的,而且创建一个包含有100万个元素的列表,占用了很大的存储空间。如我们只需要访问前1W个那后面的元素全部浪费了。
    所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
    

  • 生成器的实际运用

  • 迭代器

实质:迭代器就是可循环可遍历,就叫做迭代器。

Python的模块

  • 函数 -> 类 -> 模块 -> 包

模块分为三种类型:

1.自定义模块
2.内置标准模块(又称标准库)
3.开源模块

开源的模块地址:

https://pypi.python.org   #可以自己上传自己的模块百度就可以
  • Python的time模块

  • Python的random模块

实现生成随机验证码:
import random,string
print(string.ascii_uppercase) #所有的ASCII对应的大写字母
print(string.ascii_lowercase) #所有的ASCII对应的小写字母
print(string.digits) #所有的数字0~9
source=string.ascii_uppercase+string.ascii_lowercase+string.digits
print('验证码:',''.join(random.sample(source,4)))
  • Python的运维常用模块OS模块

异常处理

异常处理一:
while True:
    try:
        x = int(input('please input a number:'))
        break
    except ValueError:
        print("Oops! that was no valid number. Try agin")
异常处理二:

Pyhton的框架Flask

介绍:
Flash短小精悍,内部没有太多组件,第三方的组件非常丰富。

  • Flask入门学习

1.安装:

pip3 install flask
  • 配置文件的学习

  • 路由系统

  • 模板语言

  • 请求和响应相关

  • Session和cookie保存方式

  • 瞬移

  • 蓝图

  • 请求的扩展(django中间件)

  • 中间件

发表评论