博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Py日记(python零起步
阅读量:3950 次
发布时间:2019-05-24

本文共 11568 字,大约阅读时间需要 38 分钟。

谨以此blog记录我的python学习之路和给其他初学者参考。

我看的书是像计算机科学家一样思考Python,看起来B格很高,但其实非常好入门,并没有很理论(大概名字高级好卖一点 )

一、程序之路

安装好python3,设好环境变量后,在命令行敲个python就可以进入码代码的模式了。新的语言自然是从Hello World开始

>>> print('Hello,World!') #输出Hello,World!

这个程序体现了三个信息。

  • print()是输出啦~
  • #后面是注释啦~
  • 字符串可以用单引号括起来~(也可以用双引号)

Then Py还可以做一些类似计算器的工作(从此不用电脑的计算器

>>> 2 * 3 ** 354>>> qwq = 9>>> qwq / 33.0>>> qwq // 24

我们可以发现我们输入一个表达式,会求出最终值给我们。这里的**是指数运算的意思,//是向下整除法。其他运算基本就是c语言了。(我学过c,c++。所以跟c,c++相似的就不赘余了

二、变量、表达式和语句

赋值,变量名称要求和c语言一样。表达式和语句的区分:

>>> n = 10 #语句>>> n + 4  #表达式14

语句通常没有值,表达式有最终值。

前面这些都是interactive mode下运行python,也就是一行一行地在命令行写并执行。还可以在文件里写,也就是script mode。两者区别就是表达式在script mode下不会输出他的值,想输出要print()。

字符串操作,有两个,+ 和 *。+ 就是拼接。*就是重复字符串几次(必须 * 整数。

>>> 'Mr'+'chen116''Mrchen116'>>> 'BBZ' * 4'BBZBBZBBZBBZ'

三、函数

代码说话

>>> type('454')
>>> type(5.5)
>>> int('49')49>>> float('23.8')23.8>>> int(-16.7)-16

type()输出参数的类型,类型转换则c++类似,int(),str(),float(),三者可以相互转。

要用数学函数就要有数学的模块(module)

>>> import math>>> math
>>> math.sqrt(49)7.0>>> math.sin(math.pi/6) #弧度制,瞧他还有浮点误差0.49999999999999994

可以看到math是一个module object。用’.'可以使用module object里面的变量和函数。值得注意的是,三角函数用的是弧度制,而不是角度。

有了以上的知识,python是一个很好的计算器了

写函数~

>>> def print3(mySTR):...     print(mySTR*3)...>>> print3 #可见定义其实就是创建函数对象,但是不直接执行函数体的语句。
>>> print3('您好~')您好~您好~您好~

Py中函数def定义函数,括号内是参数,然后:后面就是函数体,函数体用缩进来表示,相当于c的{ }。后面就可以调用这个函数了。

然后形参跟实参的关系跟c类似啦,但由于形参的类型并没有固定,所以会跟随实参的类型。然后函数里面的变量包括形参都是局部变量啦~
这里的函数是无返回值的,如果强行用它的值,会发现他是None。不是字符串,而是None type的。

>>> res = print3('~')~~~>>> print(res)None>>> type(res)

四、案例研究:接口设计

这一章比较好玩,用来熟悉语法。这一章就开始用script mode了,也就是搞个IDE玩。

介绍第二个module:turtle,用来画图。就是一只乌龟,走到哪,哪就留下一条边。

import turtlebob = turtle.Turtle()

运行这个代码就会弹出白窗口,箭头就是小乌龟了!这里bob就是一个Turtle对象了,也可以做很多个Turtle对象,也就是会出现很多个箭头。

下面是对?的一些操作:

bob.fd(10) #向前走10pxbob.lt(90) #左转90度bob.rt(60) #右转60度

然后我就用这个做了方形,圆形,菊花。。。

import turtleimport mathbob = turtle.Turtle()qq= turtle.Turtle()def polygon(t,r):    '''plot半径为r圆形'''    n=r    len = 2*r*math.pi/n    for i in range(n):        t.fd(len)        t.lt(360/n)def arc(t,r,angle):    '''plot半径为r角度为angle的圆弧'''    n=r    len = 2*r*math.pi/n    for i in range(int(angle/360*n)):        t.fd(len)        t.lt(360/n)def petal(t,len,angle):    '''plot长度为len展角为angle的花瓣'''    r=int(len/math.sin(angle/180*math.pi/2))    arc(t,r,angle)    t.lt(180-angle)    arc(t,r,angle)def flower(t,num_petal,len):    '''plot num_petal个长度为len花瓣的花朵'''    angle=int(360/num_petal)    for i in range(num_petal):        petal(t,len,angle)        t.lt(180)def square(t,len):    '''plot方形'''    for i in range(4):        t.fd(len)        t.lt(90)square(qq,30)flower(bob,12,150)#while 1:#    i = input()#    if i == 'a':#        bob.lt(90)#    elif i=='d':#        bob.rt(90)#    elif i=='w':#        bob.fd(10)#    elif i=='s':#        bob.rt(180)#        bob.fd(10)

上面的三点,是多行字符串的意思,也就是可以保存换行

mySTR = '''Hello World''' print(mySTR)

五、条件和递归

逻辑操作符: and or not 即与或非啦~

条件

i = 24if i > 0:   print('qwq')elif i < 0:   print('QAQ')else:   print('GB')

递归

def print_num(n):    print(n)    if n > 0:        print_num(n-1)print_num(8)

输入 input() 函数,参数可有可无,为输入提示信息。

ans_me = input("What's your problem?\n") #字符串有'用双引号,\n是换行print("This's your problem. " + ans_me)

六、有返回值函数

就是加个return 啦~

由于函数参数并没有限定,而很多时候需要指定类型的参数,就可以用到一个判断类型是否为某类型的函数isinstance(),返回类型是bool。

>>> b = 6>>> c = 'v'>>> isinstance(c,str)True>>> isinstance(b,str)False>>> isinstance(b,int)True

七、迭代

用一个平方根,介绍一下whilebreak的用法。这里用牛顿迭代法做一个开平方跟熟悉这两个语句。

a = float(input())x = aepsilon = 1e-6while True:    print(x)    y = (x + a/x) / 2    if abs(y-x) < epsilon:        break    x = yprint(x)

我学到这就开始有点无聊了

八、字符串

字符串就非常好玩了~~~

>>> fruit = 'apple'>>> type(fruit[0])
>>> fruit[-1]'e'>>> len(fruit)5

字符串就是字符序列,于是我就好奇那里面的单个字符是什么类型呢?结果是仍然是str。同时Py中下标也是从0开始。因缺思汀的是负整数同为合法的下标,从右往左编号,第一个是-1。len函数就是字符的个数。

切片

>>> fruit[0:3] #冒号前后表示一个区间,包含左边的,但不包含右边的,因此没有'l''app'>>> fruit[:3]  #省略第一个,就是从头开始'app'>>> fruit[2:]  #省略第二个,就是到结尾'ple'>>> fruit[4:0]  #第二个≥第一个,就会是空串''

for循环遍历

>>> for cha in fruit:...     print(cha)...apple

特殊:字符串不能改变里面某一个字符

>>> fruit[1] = 4Traceback (most recent call last):  File "
", line 1, in
TypeError: 'str' object does not support item assignment

表明str作为一个object,是一个整体,而里面字符只是一个item。

字符串方法

>>> fruit.lower()     #返回字母都变为小写'apple'>>> fruit.upper()     #变成大写'APPLE'>>> fruit.find('pl')  #查找字符串在原串中的首位置2>>> fruit.find('p',2) #接受第二个参数,为开始查找的位置2>>> fruit.islower()   #返回是否全为小写字母,同样还有isupper()True>>> fruit.capitalize() #若第一个字符是字母,则将其变成大写;其他字母变小写'Apple'

布尔操作符in

返回第一个str是不是第二个的子串。

>>> 'pl' in fruitTrue>>> 'awp' in fruitFalse

于是就可以写出这种类似英文的代码,找出两个串中相同的字符。

def in_both(word1,word2):    for letter in word1:        if letter in word2:            print(letter)in_both('What','the')

九、案例分析:文字游戏

代码说话

fin = open('Py1.py')    #读入文件的方法,返回一个file for line in fin:        #逐行读入    print(line.strip()) #strip()方法是去除行首末的指定字符,未指定则默认空格和换行

逐行读取还有一个函数

fin.readline()

十、列表

列表一般用方括号括起来

>>> li = ['xixi', 2.5, 6, [4, 7]] #列表可以存各种类型>>>> li[0] = 'haha'               #这是合法的>>>> 6 in liTrue>>> li + li[-1]['haha', 2.5, 6, [4, 7], 4, 7]>>> li[2:4][6, [4, 7]]>>> li[2:4][6, [4, 7]]

可以看到列表还可以嵌套,而且列表元素是可变的。而且可以用in操作符。遍历方法同str差不多,都可以用遍历元素或遍历下标。同样的,列表有加法和乘法,与str一样的用法。切片的用法也一样。

列表方法
见注释

>>> li.append('DIAO')      # 添加一个元素>>> li['haha', 2.5, 6, [4, 7], 4, 7, 'DIAO']>>> li.extend(['Q','E'])   # 添加列表所有元素到里面>>> li['haha', 2.5, 6, [4, 7], 4, 7, 'DIAO', 'Q', 'E']>>> bb = ['a','E','c','1','A']>>> bb.sort()              # 对列表内元素排序,无返回值>>> bb['1', 'A', 'E', 'a', 'c']>>> bb.pop()			   # 删除最后一个元素,同时返回它!'c'>>> bb.pop(0)			   # 删除下标是0的元素,并将其返回'1'>>> del bb[0]			   # 若不需要其值,可以直接del>>> bb['E', 'a']

列表和字符串

>>> STR = 'split me'>>> li = list(STR)  # 把字符串分成单个字符的列表>>> li['s', 'p', 'l', 'i', 't', ' ', 'm', 'e']>>> t = STR.split() # 此方法可按空格分开>>> t['split', 'me']>>> STR = 'Go!Euler!Oh!'>>> STR.split('!')  # 同样可按你要求的分隔符['Go', 'Euler', 'Oh', '']

对象和值

来一段诡异的代码:

>>> s = 'are'>>> b = 'are'>>> s is bTrue>>> l1 = [1,2,3]>>> l2 = [1,2,3]>>> l1 is l2False

这里显示出s和b是同一个字符串的引用,而l1,l2不是同一个对象,只是值相同。有没有想起str不能改变,而list可以改变这个特性!?相信你知道了!

别名
理解了上面那个,看这个就更加诡异了~

>>> a = [1,2,3]>>> b = a>>> a is bTrue>>> b[0] = 6>>> a[6, 2, 3]

刚说完不同,这又来了个True,这证明b只是a的别名。当我改变b的时候,a也改变了。

列表参数

def del_head(li):    del li[0]t = [1,2,3]del_head(t)print(t)    # [2, 3]

当以列表为函数参数时,传的是引用,即改变形参,会影响实参的值

然鹅。。。

def del_head(li):    li = li[1:]t = [1,2,3]del_head(t)print(t)    # [1, 2, 3]

这又是为什么呢?因为切片时其实新建了一个新的列表,所以最后li已经不是实参的引用了。同样,下面的加法也创造了一个新list。

def add_end(li):    li = li + [7]t = [1,2,3]add_end(t)print(t)    # [1, 2, 3]

十一、字典

字典就是映射。犹如c++ STL中的map一样,下标可以是任意类型。(回顾一下,下标->,另外一个是

>>> di = dict()        # 创建空字典>>> di['one'] = 1	   # 添加key-value pair>>> di['two'] = 2>>> di{
'one': 1, 'two': 2}>>> di['one'] # 查找某个值1>>> di['four'] # 若没有就ErrorTraceback (most recent call last): File "
", line 1, in
KeyError: 'four'

与STL map不同,Py的dict是用hashtable的方式存的。具体后面再谈。下面用统计单词的各个字符出现的次数的函数来进一步熟悉dict。

def func(s):    d = dict()    for c in s:        if c in d:     # 判断一个键是否在字典中            d[c] += 1        else:            d[c] = 1    return dmyS = 'Tencent'di =func(myS)for x in sorted(di):  # sorted函数会把di的键进行排序,返回值是一个键的list    print(x,di[x])

dict还有一个方法get(),接受一个键和一个默认值,若找不到对应键就返回默认值,所以上面的func() 也可以这么写

def func(s):    d = dict()    for c in s:        d[c] = d.get(c,0)+1    return d

反向遍历,实际上并没有太好的方法。

def reverse_lookup(d, v):    for k in d:        if d[k] == v:            return k    raise LookupError('value does not appear in the dictionary!')di = {
'a':1,'b':2,'c':3}print(reverse_lookup(di,2))

这里有个新语句raise,它会产生一个异常,这要生成的异常是LookupError 这是一个内置异常。那个描述错误细节的参数是可选的。当找不到对应value是程序就会输出

Traceback (most recent call last):  File "
", line 1, in
File "
", line 5, in reverse_lookupLookupError: value does not appear in the dictionary!

字典与列表

列表可以是字典的一个值,下面举一个反转字典的例子。

def invert_dict(d):    inverse =dict()    for key in d:        val = d[key]        if val not in inverse:            inverse[val] = [key]        else:            inverse[val].append(key)    return inversedi = {
'a':1,'b':2,'c':1}print(invert_dict(di))

输出为{1: ['a', 'c'], 2: ['b']}。但是列表并不能作为字典的键,毕竟列表无法hash,而且它是可变的。从而你也可以猜到字典也是无法作为键的,因为它也是可变的。

全局变量

并不懂作者为什么放全局变量在字典这一章,可能没地方放吧

这里主要是讨论全局变量在函数中的问题。

在函数内若未声明全局变量,仍然可以使用它的值:

c = '乌里妈查'def p():    print(c)   # 正确p()

然而,你想改变它的值,那就不行了:

c = '乌里妈查'def p():    c = 'M . M'p()

因为Py会默认c是新建的一个局部变量,并不会改变全局变量的值。基于此,下面这段代码就会报错了,因为局部变量c压根还没定义。

c = '乌里妈查'def p():    c = c + '!' # 错误p()

所以当我们要在函数内修改全局变量的值时,就要声明,告诉编译器这是全局变量,不要给我新建一个局部变量!

c = '乌里妈查'def p():    global c    c = c + '!'p()

但是,若全局变量是可变的值,你也可以不用声明就修改它。所以可以添加、删除和替换一个全局的列表或字典的元素。

d = {
0:'a',8:'w'}def p(): d[2] = 'Q'p()print(d)

但是,要想给全局变量重新赋值,则需要声明啦~

d = {
0:'a',8:'w'}def p(): global d # 必须声明 d = dict()p()print(d)

这样听起来会特别乱。概括起来就是全局变量不声明时,可以作为右值访问,不能整个对象作为左值,而要是全局变量是可变的,就可以改变其值,但仍然不能作为左值进行重新赋值。

不明白莫得关系,多试试

十二、元组

元组各方面跟列表差不多,但是元组是不可变的!创建元组的几种方式如下:

t = 'a','b','c't = ('a','b','c')t = tuple('abc')

上面三种都是等价的。tuple()不带参数是新建空元组,参数是序列(str,list,tuple)就会生成包含序列的元素的元组。

Py序列比较大小,从第一个元素开始,逐个比较到不同元素为止。

>>> (0,1,123)<(0,3,-9)True

元组赋值

优雅地交换两个变量的值

b,a = a,b

魔性吧!左边是变量的元组,右边是表达式的元组。每个值会一一对应。但是左右必须变量个数相同,不然就Value Error了。更一般的,右边可以是任何序列。

address = 'Mr.chen@qq.com'name,domain = address.split('@') # 返回list

上面的代码就可以把用户名和域名分开了。

遍历元组列表

t = [(1,11),(2,22),(3,33)]for index,value in t:    print(index,value)

作为返回值的元组

严格说,函数只能返回一个值。但这个返回值可以是元组,那就跟返回多个值差不多了。内置函数divmod()就是返回了(商,余数)这个元组。

divmod(11,3)(3, 2)

你也可以用return a,b,c来写自己的函数。

可变长参数元组

函数可以接受不定个参数。只要形参前面加个*,所有参数都会 收集(gather)到这个元组上,反操作是分散(scatter),在调用形参不是接受元组,而是接受多个参数时,在实参元组前面加*。

def print_all(*arg):    print(arg)tu = 11,3print_all(tu)print(divmod(*tu))

结果是:

((11, 3),)(3, 2)

下面介绍一下,内置函数中哪些是接受可变长元组,哪些是不接受

max(1,2,4,6)  #正确min(1,2,4,6)  #正确sum(1,2,4,6)  #错误

列表和元组

zip() 接受两个或多个序列,并返回一个元组列表。每个元组包含一个元素,就像拉链一样把各个序列里的元素对应起来。例如:

s = {
2:4,3:9,4:64}t = [5,6,7,8]q = "What???"tmp = zip(s,t,q)print('tmp:',tmp)for e3 in tmp: print(e3)print('list(tmp): ',list(tmp))print('zip(s,t,q): ',list(zip(s,t,q)))

输出

tmp: 
(2, 5, 'W')(3, 6, 'h')(4, 7, 'a')list(tmp): []zip(s,t,q): [(2, 5, 'W'), (3, 6, 'h'), (4, 7, 'a')]

这反映的几个特性

  • zip函数返回的是一个zip对象
  • zip对象是一种迭代器,跟列表类似,但不能下标访问,而且只能遍历一遍( for里遍历了tmp,所以tmp最后为
  • 元组的个数有len最小的序列决定
  • 元组里元素的顺序由参数顺序决定
  • 要是序列是字典,实际上只用了键,没用值
  • zip对象可以转换成list对象

zipfor组合起来就可以同时遍历多个序列。例如寻找是否有s1[i] == s2[i] 的程序

def has_match(s1,s2):    for a,b in zip(s1,s2):        if a == b:            return True    return False

案例研究:选择数据结构

这章主要在于如何灵活地应用各种Py核心数据结构。

读入文件拆分为单词,并转成小写

这里用到了string module的whitespace(空白字符串),punctuation(所有标点符号)。

import stringfin = open("text.txt")out = ""for line in fin:    for char in line:        if char in string.punctuation+string.whitespace:            out+=' ';        else:            out+=char.lower();    out+='\n'outlist=out.split()print(outlist)
统计文件中单词总数以及每个单词使用的次数

用这个去扒书统计还是很有意思的。

import stringfin = open("text.txt")out = ""for line in fin:    for char in line:        if char.isalpha():            out+=char.lower();        else:            out+=' ';    out+='\n'outlist=out.split()dic = dict()for word in outlist:    dic[word] = dic.get(word,0)+1moreThan20Word = dict()for word in dic:    if dic[word] >= 20:        moreThan20Word[word] = dic[word]print(moreThan20Word)

然而看了标程后,羞愧不已。

import stringdef process_file(filename):    hist = dict()    fp = open(filename)    for line in fp:        process_line(line,hist)    return histdef process_line(line,hist):    line = line.replace('-',' ')    for word in line.split():        word = word.strip(string.whitespace+string.punctuation)        word = word.lower()        hist[word] = hist.get(word,0)+1hist = process_file("text.txt")
随机数

文件

类和对象

类和函数

类和方法

继承


转载地址:http://mwuzi.baihongyu.com/

你可能感兴趣的文章
CheckPoint关键词做字段名使用.
查看>>
Qt QSplitte分割器使用(用户手动改变窗口大小)
查看>>
Qt动态加载动态库
查看>>
java8新特性
查看>>
git clone时RPC failed; curl 18 transfer closed with outstanding read data remaining
查看>>
Java8内存模型—永久代(PermGen)和元空间(Metaspace)
查看>>
maven中jar、war、pom的区别
查看>>
maven之pom.xml配置文件详解
查看>>
java基础学习之抽象类与接口的区别
查看>>
java基础学习之包、类、方法、属性、常量的命名规则
查看>>
java基础知识学习之匿名内部类
查看>>
SSM框架和SSH框架的区别
查看>>
Elasticsearch-基础介绍及索引原理分析
查看>>
过滤敏感词算法
查看>>
linux学习之shell脚本if判断参数-n,-d,-f等
查看>>
linux学习之windos文件在linux里面乱码解决
查看>>
idea快捷键
查看>>
linux学习之shell遍历数组
查看>>
python函数取参及默认参数使用
查看>>
linux学习之shell中的${},##, %% , :- ,:+, ? 的使用
查看>>