Python数据类型与函数精髓全解析 1、输入2、数制所谓的浮点数, 其实指的就是小数。它之所以被叫做浮点数, 主要是因为在采用科学记数法来表示的时候, 一个小数里面那个小数点的位置是可以变动的。打个比方说, 一点零和十二点三乘以十的八次方, 这两个数值是完全相等的。另外呢, 浮点数还能够用数学里的那种常见写法来写出来, 比如说一点二三、三点一四, 还有负的九点零一, 诸如此类的例子都算在内。对于非常大的浮点数或者是非常小的浮点数, 就必须得用科学计数法来表示, 把10换成e来替代。1变成1.23e9或者12.3e8,.0改成1.2e-5等等。3、布尔值只有true和false这两个值, 可以使用and, or以及not来表示与、或、非的意思, 这同时也是if在做判断处理时所得到的那个结果。4、空值 None并不是05、那个变量是能够被进行重复一次的赋值操作的, 并且在这种情况下所赋予进去的值是可以出现不同情况的。所谓的动态语言, 指的就是变量不固定的语言。其实吧, 也可以把变量赋给另一个变量, 而这么一做的话, 其本质上就是在进行数据的赋值操作。6、这句话的意思是指一种针对地板进行的除以操作, 也就是进行除法计算, 算完之后只提取那个整数部分的内容。7、字符串:ASCII这个编码方式, 它占1个字节的长度, 而UTF-8这种编码呢, 对于汉字来说, 它是3个字节, 对于英文字符来说, 则是1个字节。从这个时候起, 开始对中文进行支持。把-ord()这个表达, 给转化成整数。-chr()转化成中文那个所谓的减号后面跟着的十六进制数是四百二十四这个字符, 它所对应的整数形式的编码数值, 恰好就是等于一个字的大小。那个在横杠后面的str, 它能够通过点后面跟着的那个括号里面写着acii的内容, 被编码成指定的bytes, 然后那种通过网络获取到的byte数据文件, 它是可以使用点后面跟着的空括号, 按照大家说好的指定方法来解码变成。-len计算长度8、就是为了让Linux系统知道它是个可以运行程序, 所以才加了#!/usr/bin那一行。codeutf-8是为了告诉解释器按照utf-8编码读取源代码7、在处理那些字符里面带有变量的输出问题的时候, 它和C语言是一样的, 也是使用占位符%s这样的方式来代替比如说hhh这种内容, 除此之外还会涉及到点号的操作。8、的各种数据组1list-,有序集合, 是使用list来进行访问的, 此时list指的是倒数第一个。它是可变的, 可以利用追加元素或者插入到指定位置来实现变化, 也可以通过pop删除末尾元素, 或者直接对那个元素进行赋值操作, 比如把这个元素的class设为new1。这个元素的内容是非常随意的, 如果它本身也是一个这样的结构的话, 那么整体上就会变成二维数组的形式。2这是一个叫作tuple的东西, 它的括号里是空的, 在初始化完成之后, 它是不能够被更改的一个按顺序排列的集合, 所谓的不变指的是指向这个对象的地址是不变的, 要是说tuple里面的list如果发生了改变, 那么从结果上看的话它还是会变成别的东西。9、条件判断if age19:当在输出语句中并没有设置任何占位符的时候, 它的意思就是直接按照原样进行打印和显示。elif ageprint(更加细致的判断)else:输出包含fuck guys的这个文本信息, 这里不需要使用分号。只要那个条件被满足了, 等把这个相关的操作全部执行完毕以后, 后续的那几个步骤或者分支就直接跳过不干了。需要注意, 当输入的量默认是字符串类型的时候。关于格式转换这回事, birthint(s)这一行代码之所以成立, 主要是因为int这个大整数类型在程序界的规定里, 只能被用于那些已经能够实现转变为整数的操作上面。10、解释器和编译器有什么区别11、循环, 分为两种类型。1for 变量 in list/tuple()依次地对list和tuple里面的每一个元素来进行迭代。names,for name in names:print(name)2 当条件判断成立的时候, 只要这个条件是满足的, 那就不断地去进行循环。while n0:n n - 23由函数range(5)所生成出来的那个序列, 它包含的都是一些整数, 而且这些整数的值是从0开始一直累加到4为止。使用break这个命令来提前把那个循环给它结束掉。跳过当前这次循环。什么意思呢? 比如说是当情况变成偶数的那个次的时候, 就提前结束本轮的这个循环过程。你只需要把CtrlC按住, 然后按一下那个C键, 这样你就可以退出这个程序。12、使用dict和set1这个词典, 它又被称为映射关系的映射, 采用的是键值对的存储方式, 因此进行查找操作的速度是十分快速的。names a,b,c对应dict d{a:99,b:12,c:11}-直接取da这样就可以, 或者直接选择用等号来执行赋值动作。通过检查变量d之中是否包含了字符a来进行判断。可以用d.get这个方法去取值, 它有的时候能取得一个具体的数值, 有的时候会返回none, 或者按照你设置的情况返回指定的一个值, 比如在d.get这个调用里面传入a和负一这两个参数。通过调用d.pop(a)这个方法, 我们也是可以把名为a的这个数据进行删除操作的。那个被叫做 -key 的东西, 它必须是不可变对象。简单说来, 就是不可以是那种叫做列表的玩意儿。2set, 这是key的集合, 但是它是不存储value的, 因为key是不能重复的, 所以, set也是不可以重复的, 它是无序且不可重复的集合。的创建行为, 它其实是能够基于一个已经存在的列表来进行实现的, 大家通常会通过调用的方式来让这个变量等于那个用括号包裹起来的列表对象本身。1,23,2,1,2-s.add(key) (key就是任意想让它当key的值) 可以添加值到set中-s.(key)可以移除一个元素这个动作是不可以的, 不要往里头加入那个可变对象, 具体来说是一个列表list。13、对于字符串a来说, 如果我们使用了类似a.((a,A))这样的操作。实际调用的方法是在字符串对象上执行的。执行完毕以后会返回一个新的对象为A。这个操作并没有改变原来a的内容。在现在这种情况下如果用ba的方式来赋值。变量b就会再次指向那个新的字符串对象。当面对不可变对象的时候, 如果去调用该对象本身所具备的任何一种方法, 那么这种做法是绝对不会使得当前这个对象里面的内容发生改变的一种情况的, 相对于这种不会改变自身内容的状况相反的另一种做法是, 通过这些调用的方法会创造出全新的一个或多个对象, 并且把这些新创造出来的对象作为返回值交付给调用者, 这样一种操作机制的存在, 就可以确保被称之为不可变的对象在很长的一段时间里都能够一直保持着不可变的状态。(1,2,3)属于那种无法被更改的对象, 但是(1,2,)就不一样了, 它并不是一个不可变的对象。14、函数1抽象的意思是什么呢? 它告诉我们, 函数也是一种抽象的方式。这种方式的存在, 可以帮我们站在一个更高的角度来去思考问题。2调用名称是: 只要你知道了函数的名字就可以直接进行调用, 至于具体的详情内容, 你可以去查阅官方的文档资料以获取相关信息。3函数名本身其实就是一个指向函数的对象的引用, 因此我们可以把函数名赋值给一个变量, 这相当于给这个函数取了另外一个名字作为别名。4定义def myFun():if x大于1, 那么。这是函数的返回值, 当执行到这个位置的时候, 就会认为函数已经执行结束了, 如果没有写任何语句的话, 默认会返回none这个值, 另外也可以直接只保留一个特定的返回值。-出现...是正在定义函数按两次回车可以回到界面-如果我已经把def定义的函数保存在file.py中我可以在同一个目录下使用from file func来导入这个函数了如果想要定义一个什么事情都不需要去做的操作, 那么就去使用pass, 这个主要是用作之后还要进行补充的函数的占位符。它会帮你检查参数的个数, 但是它对参数的类型是检查不出来的, 这一点需要我们自己去进行定义, 具体的定义方法如下:def (x):如果 x 不是整数, 也不是浮点数的话。raise (bad type)5这个操作会返回好几个值出来。def move (x,y)nx,ny使用x,ymove(1,2)或者你可以使用一个独立的变量来接收这个结果, 从实际的情况来看, 这个方法的返回值其实是一个由多个元素组成的元组。6函数的参数必选参数默认参数可变参数关键字参数。关于那个位置参数。def power(x,n):x*xn, 此时此刻的x和n是位置参数, 会按照你在传入的时候写上去的位置顺序, 然后把相应的值依次分配给参数x和参数n。-默认参数def power(x,n2):就上面的那个情况来说, 要是只传x的值也是完全可以的。在设置这些被默认赋予的参数的过程当中, 有一点需要特别加以注意。必须把必选项放在前面, 然后把默认项放在后面, 要是反过来的话, 就会出现错误, 造成报错, 这是因为系统进行判断的时候, 是按照具体的位置来进行处理的。把那些变化幅度比较巨大的参数, 放到列表的前面去, 而那些变化不太大的参数呢, 就放在后面, 这么做主要是为了把它们设置为默认参数, 因为从实际情况来看, 它们的数值在很多场合下面很有可能会是固定的或者说是重复出现的。如果你想要在不按照顺序提供那个默认参数的时候, 就写power(1,naaa)。这里的意思就是, 你要特地告诉解释器, 说你现在是要传n这个参数。大家一定要记住, 在使用默认参数的时候, 必须得把那些不会变化的对象指向给它们, 否则要是每次运行程序的时候都有改变发生, 这种改变就会被一直留在原地保留下来, 具体的表现例子在下面这里展示给大家看。默认参数这个东西是有用的, 但是如果你使用得不恰当的话, 也是会掉进坑里面的。默认参数有一个最大的坑, 接下来就会给你演示一下, 具体是怎么样的。首先定义一个函数, 把这个list传进去作为参数, 然后再添加一个END, 最后返回这个结果。def add_end(L[]):L.append(END)return L当你正常调用时结果似乎不错 add_end([1, 2, 3])[1, 2, 3, END] add_end([x, y, z])[x, y, z, END]当你使用默认参数调用时一开始结果也是对的 add_end()[END]可是, 再一次把那个括号里面什么都没有的参数给传进去让程序去执行的时候, 最后拿出来的结果就不准确了: add_end()[END, END] add_end()[END, END, END]很多刚开始学习的人感到非常困惑, 他们原本以为默认参数应该是什么样子的, 但是实际情况却是这个函数好像每次都记着上次添加了END之后的那个列表。具体的原因说明, 如下进行。函数被定义的时候, 默认参数L的值就已经计算完毕了, 也就是说, 鉴于默认参数L本质上也是一个变量, 并且它指向的是某个对象, 所以当人们每次调用该函数, 只要修改了L的内容, 那么在接下来的调用过程当中, 默认参数所携带的内容就发生改变, 不再维持函数被最初定义时的那种状态。在对默认参数进行定义的时候, 有一点是需要被牢牢记住的, 那就是: 默认参数必须得要指向一个不会改变的对象为了去修改上面提到的那些个实例的情况, 我们这里能够利用到None这个不会发生变化的一类东西对象, 来把它给实现出来:def add_end(LNone):if L is None:L []L.append(END)return L当前这个情况之下, 无论用户去执行调用操作多少次, 都是不会有出现问题这样的结果的。要问为什么要设计像None这样的不变对象, 还有str这样的不变对象, 这是因为不变对象一旦被创建之后内部的数据就不可以被修改, 这就减少了由于修改数据而导致的错误, 此外, 因为对象是不变的, 所以在多任务的环境下, 读取该对象就不需要加锁, 可以实现并行地读取, 所以, 如果可以设计成不变对象的话, 就应该尽量把对象设计成不变对象。-可变参数所谓可变参数这个东西, 它是这么个意思, 就是传入的那种参数的数量, 是可以发生变化的, 这种变化可以是1个, 可以是2个, 也可以多到任意的数目, 甚至可以是0个。在当传入的内容为list以及tuple这类的结构时, 可以对其进行如下的这种写法操作。定义一个用于计算的函数, 名字叫作calc。sum0for n in :sumsumn*nsum但是在调用的时候需要你自己先去组装好tuple或者是list。这种情况是存在于那些部分所有的参数都会被接受的地方。然后要接收进来对运算进行判断看运算能不能接受这个函数。除非你自己去写一个预判断的函数。如果是可变参数方法的话。def calc(*):那个总和等于零。for n in :sum sum n*nsum在这个时候进行调用的方式, 只需要去写出来calc这个函数括号里面是1逗号2逗号3就可以了。在函数内部接收到的那个值是一个元组, 可是现在是可以往里面传入任意个参数的, 并且这个数量的上限是不存在的, 所以哪怕是零个参数也是可以传进来的。假如现在有一个叫做list的东西, 它想要去调用那个可变参数的话, 大家可以选择使用cal这样的写法, 而且括号里面要写三个list, 也就是成那种cal(list,list,list)的样子。或者是直接使用cal这个函数名, 但是后面跟上星号, 再加上list这几个字母, 简写成cal(*list)这种方式也是可以的。关于那个list前面的星号代表的意思是明确的, 它的意思就是把list内部所有的元素都拿出来当作那个可变参数给传进去。这种写代码的方法在实际情况中是非常有用的, 同时它也是一个十分普遍并且常见的技巧。-关键字参数可变参数这种机制, 可以让用户往里头传0个参数进去, 也能够传任意数量的参数进去。这些传入的参数呢, 会在程序里头自动就给组装成一个tuple类型的数据结构, 而关键字参数这种玩法, 它能够允许你往函数里面传入0个带有具体名字的这个参数, 当然也可以是任意的、带名字的参数也行, 这些带名字的关键字参数在函数的内部会自动地给组合在一起, 最终形成一个类似于字典这样的dict数据结构, 举一个具体的例子来看的话。def (name,age,**kw):printname, age, kw这里说的kw啊其实就是被叫做关键字参数那个东西。可以只传入前两个必选参数这样的话最后一个会显示为{}再往后一点就是如果说是需要去传入那个关键字参数了的话, 那么这里面的一个具体的例子的形式呢, 就会是用单引号引起来的空字符串, 然后是一个逗号分隔的数字一十二紧接着再来一个由等号以及后面的单引号所包裹的空构成的一个完整的部分。这个输出的内容会显示为这样一个形式, 也就是一个以逗号开头, 后面跟着数字12, 接着是一个花括号, 花括号里面包含了一个用单引号标记的城市字段, 而这个城市字段的值目前是一个空字符串。关键字参数的作用是什么呢, 简单来说就是为了去扩展功能。可以先把字典给提取了出来, 然后把它传入到那个办法里面去, 以便传入这个类型的变量, 也可以不用这么麻烦, 直接用那种简化的写法来操作比如在括号里填上那些内容、数字一百二十, 再加上两个星号加上那些额外的东西, 最后再把字典传进去。extra {city:,job:}如果, 要是需要在那个函数里面去检查一下, 看看传进来的这个数据里面到底有没有包含某一个特定的参数情况的话, 就可以。如果city在kw里面。在这个情况下, 里面包含了城市这个参数。pass如果说要限制一下那个关键字参数的名字, 那么就可以考虑去使用那种被称作命名关键字参数的东西来进行操作, 比如说。def (name,age,*,city,job):print(city)这个和那个kw是不一样的, 命名关键字参数是需要一个特别的分割符号星号*的, 在星号*后面的那些参数会被当成是关键字参数来看待, 然后呢, 就像那个比如*args这种可变参数它后面的参数也都会被看成是关键字参数, 不过只能是传入了字典才行, 命名关键字参数也是可以设置上默认值的。你要记住, 如果可变函数这个地方没有加*做分隔符的话, 系统是没有办法识别出来的。-参数组合组合顺序是先把必选参数放在前面, 然后把默认参数放到后面, 接着再处理可变参数, 随后引入命名关键字参数, 最后才安排关键字参数。比如说def f1(a,b,c0,*args,**kw):def f2(a,b,c0,*,d,**kw)具体的使用方法应当是这样的。还有一种调法, 就是用一个 tuple 配合一个 dict, 来进行函数调用。对于任何函数, 都能够采用类似于func(*args,kw)这样的形式去对它进行调用, 不过关于参数方面的组合设置, 建议大家还是不要写得过多比较好, 如果写得太复杂的话, 很容易就会发生混淆的情况。6递归函数当一个函数在它自己的内部区域当中去调用它自身的时候, 那么这种函数就被定义为递归函数。def fact(n):if n1:return 1return n * fact(n - 1)使用递归函数的过程中, 人们需要去防止出现栈溢出的状况这主要是因为对于计算机而言, 函数调用的行为是依靠被称为栈的这样一种数据结构来予以实现的, 每当进行一个函数调用操作的时候, 栈就会增加一层的栈帧结构, 而每当函数执行完毕并返回的时候, 栈就会减少一层的栈帧结构。针对递归调用时出现栈溢出问题的解决办法, 就是采用尾递归优化技术。实际上呢, 尾递归和循环所达到的效果是完全一模一样的。因此的话, 咱们把循环当作是一种特殊的尾递归函数来对待, 这同时也是完全没问题的, 也是行得通的。所谓尾递归, 就是指在函数返回的时候, 要去调用自身本身, 而且这个过程里面不包含什么表达式, 这样一来, 解释器就会进行优化操作, 使得整个递归即使执行了非常多的次数, 也只会占用一个栈帧的空间, 所以就不会出现栈溢出的情况了。如果要把上面那一段代码给改成别的样子, 那么就需要去注意一下这个点, 就是说要把每一步里面计算出来的乘法的结果呢, 给传到那个递归函数里头去用。def fact(n):return fact_iter(n,1)def fact_iter(num,product):if num 1:return productreturn fact_iter(num - 1,num* product)#仅返回递归函数本身num-1和num*product在调用前就会被计算不影响函数调用#无论多少次栈也不会增加 但是python语言没有这种优化要小心栈溢出问题考虑这个方法是不是属于递归, 大家往往会选择从宏观角度去下手, 而那些细节部分的问题呢, 那就直接交给接下来的那个递归环节去处理就好了。