《Python基础编程》笔记

版权声明:作者水平有限,博客中难免不少纰漏甚至严重错误,希望大家指正。同时撰写最大的目的也在于交流学习,而不在关注和传播。任重而道远,与您共勉。 https://blog.csdn.net/yexiaohhjk/article/details/87889195

title: 《Python基础编程》笔记
date: 2017-06-02 10:37:37
tags:

  • python
    categories:
  • Python

第一章 基础知识

  • 让脚本像普通程序一样运行:代码首句 #!/usr/bin/env python告诉系统这是py文件,默认用py解释程序运行。(可惜我电脑.py文件默认打开方式是pycharm…)

  • ‘ # ‘ 行注释。

  • ’\‘ 转义字符,eg:print(‘Let\’ go!’)>> let’s go!

  • ‘’’ ‘’’ 长字符串:需要写一个跨多行或者包含特殊字符的字符串,用’’'代替普通引号。

  • r 原始字符串: 输出与原始字符串里每一个保持一致;eg:print(r’Let/‘s go!’)>> Let/'s go!

  • u Unicode字符串:py3.x中所有字符串都是Unicode编码

第二章 列表和元组

  • 序列:Py含有六种内建序列:列表[],元组(),字符串,Unicode字符串,buffer对象,xrange对象。

  • 列表可以修改,元组不能修改

  • 通用序列操作:

    • 索引:访问单个元素
      • 从0开始,可以有负值(从右往左)eg: s='hello’s[-1] = ‘o’;
      • 一个函数返回值是序列,就可以直接对结果进行索引操作
    • 分片:访问一定范围内元素,是一种优雅的写法
      • 格式:number[a: b : c] 序列number从起点a到b以步长c的集合。a可为空,默认0,b可为空,默认结尾,c可为空可省略,默认1.即 number[:]表示全部。
      • eg:number=[1,2,3,4,5,6,7,8,9,10]; number[1,-2,2] >>[2,4,6,8]
    • 序列相加:通过’+'可以进行序列连接操作
    • 序列相乘:eg:初始化一个长度为10列表 sequence=[None]*10
    • 成员资格:‘in’ 判断一个值是否在序列里,也可以判断字符串是不是另一个子串。
    • 长度,最小值,最大值:内建函数len(),min(),max()
  • 列表list:[]

    • list函数:字符串->list:list(‘hello’) =[‘h’,‘e’,‘l’,‘l’,‘o’]
    • 将一个字符构成的列表->字符串:’’.join([‘h’,‘e’,‘l’,‘l’,‘o’])
    • 删除元素: del list[index]
    • 分片赋值:
      • 可以使用与原序列不等长序列将分片替换:
        eg: name=list(‘Perl’) name[1:]=list(‘ython’)
        ​ name >>[‘P’,‘y’,‘t’,‘h’,‘o’,‘n’];
      • 分片可以在不需要替换任何原有元素的情况下插入新的元素:
        eg: number=[1,5];number[1:1]=[2,3,4]; number >>[1,2,3,4,5]
      • 以此类推,分片删除也是可行的:
        eg: number=[1,2,3,4,5]; number[1:4]=[]; number >>[1,5]
    • append(val):在末尾添加元素
    • count(val):统计某元素在列表出现的次数
    • extend([]):在末尾添加多个值,比如添加一个列表里所有元素。
    • index(val):在列表里找到某个值第一个匹配的索引位置
    • insert(index,val):在index位置插入一个对象
    • pop(index):会移除列表里index位置元素,默认是最后一个,并且返回该值。
    • remove(val):删除第一个匹配val的元素,没有返回值
    • reverse():方向反转
    • sort():无返回值,注意;sorted()函数返回排好列表;
    • 高级排序,重写cmp(),sort(cmp)

-元组tuple:() 不可变序列

  • 实现一个值的元组需要加逗号:eg : (42,)
    • tuple() 函数:和list函数类似
    • 除了创建,访问元组,没有太多操作。访问也可以用索引,切片。

第三章 使用字符串

  • 基本字符串和前面序列操作类似,但字符串是不可变,初始化后就不能赋值。
  • 字符串格式化:用% 实现 eg: print(‘Price of eggs $%d’ % 42)
  • 常用方法:
    • find(val,start,end):在一个字符串里查找子字符串val,返回子串所在位置的最左端索引。没有找到返回-1.支持提供起点start,终点end。

    • val.join(list):将一个全是字符的list用val字符连接起来组成一个新的字符串。

    • lower():返回字符串小写字母版

    • replace(‘A’,‘B’):将字符串子串中’A’全部替换为’B’

    • ‘str’.split(‘A’):是join的逆方法,用A将字符串str切割成序列。
      eg:‘1+2+3+4+5’.split(’+’) >> [‘1’,‘2’,‘3’,‘4’,‘5’];
      如果不提供分隔符,会默认空格作为分隔符.

    • strip():返回除去字符串两侧空格后的字符串

    • translate(table): 需要先完成一张转换表:转换表是以某字符替换某字符的对应关系。

      利用string里 maketrans():接收两个等长字符串的参数,表示第一个字符串每个字符都用第二个字符串中对应字符代替。

      eg:

      from string import maketrans
      table=maketrans('cs','kz')
      'this is an incredibel test'.translate(table)
      >> 'thiz iz an inkredible tezt'
      

第四章:字典:当索引不好用时

  • 字典创建:

    • {} : phone={‘Alice’:‘123’,‘Bob’:‘110’}
    • dict(): 用键值对(key,vaules)来建立字典
  • 基本操作:和序列很多类似

    • len()
    • d[k]
    • d[k]=v
    • del d[k]
    • k in d:检查字典d中含有键为k的项
  • 字典的键类型为不可变元素,如整型,浮点型,字符串。

  • 字典的格式化字符串:

    phone={'Beth':'9102','Alice':'2341','Cecil':'3258'}
    print("Cecil's phone number is %(Cecil)s." % phone)
    
  • 字典方法:

    • clear()
    • copy() :深复制
    • get(key,value):访问一个不存在的健返回Node而不报错,而且可以修改权值。
    • items iteritems:
    • keys iterkeys: keys将字典键以列表形式返回
    • values itervalues: values将字典值以列表形式返回,可以包含重复的元素
    • pop(k): 将键值为k的从字典移除
    • popitem():移出随机的项
    • setdefault(key,value): 如果key不存就是添加,如果key存在,不修改返回原value.
    • update(d): 用一个字典更新另一个字典,有相同的键会进行覆盖.

第五章 条件循环其他语句

  • print(,): 逗号隔开输出内容

  • import :导不同文件函数

  • 赋值魔法:

    • 序列解包(sequence unpacking):

      • 多个赋值: x,y,z=1,2,3
      • 交换两个变量: x,y=y,x

      当函数或者方法返回元组(或其他序列,可迭代对象)时,这个特性很好用。同时所解包的序列中的元素数量必须和放置在赋值符号=左边的变量数量完全一致,否则报错。

    • 链式赋值(chained assignment)是将一个值赋给多个变量的捷径(C++中不行)。eg: x=y=z;

    • 增量赋值:x+=1

  • 循环遍历字典元素:

    • 并行迭代: 可以用序号或者zip压缩
      eg: for name,age in zip(names,ages):
    • 编号迭代: 可以使用内建函数enumerate()
      eg:
    for index,string in enumerate(strings):
        if XXXXX:
           Strings[index]='XXXX'
    
  • 循环外的else子句:神奇for里面有一个break循环下面的else就不执行,和C++不同。
    eg:找100到81之间最大平方数是81,例子中81是开区间取不到。

for n in range(99,81,-1):
    root = sqrt(n)
    if root == int(root):
        print(n);
        break
else:
    print("Didn't find it!")
    
-------> Didn't find it!
  • 列表推导式-轻量级循环(list comprehension):

    eg :[x*x for x in range(10)] -> [0,1,4,9,16,25,36,49,64,81]

    能被3整除平方数: [x*x for x in range(10) if x%3==0] -> [0,9,36,81]

    元组也行:[(x,y) for x in range(3) for y in range(3)] -> [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]

  • pass :什么都不做,可以作为占位符

  • del:用来删除变量或者数据结构一部分

  • exec(str):用字符串执行python语句 eg: exec("printf('Hhello world')")

  • eval: 用于执行python求值语句,会有一个返回值。 eg:print(eval(input("")))

第六章 抽象

  • 创建函数:def

    def fibs(nums):
      '文档字符串'
      result=[1,1]
      for i in range(nums-2):
          result.append(result[-2]+result[-1])
      return result
    

    文档字符串访问可以用 fibs.__doc __ 也可以用内建函数help()

  • 参数魔法:

    • 修改参数:传入参数是否被修改取决于该类型是否为可修改类型,如字符串,整形等不能修改,list,dict等都可以被修改:
      eg:

       def init(data):
           data['first']={}
           data['middle']={}
           data['last']={}
      
       def lookup(data,label,name):
           return data[label].get(name)
      
       def store(data,full_name):
           names=full_name.split()
           if len(names)==2:name.insert(1,' ')
           labels='first','middle','last'
           for label,name in zip(labels,names):
               people=lookup(data,label,name)
               if people:
                   people.append(full_name)
               else:
                   data[label][name]=[full_name]
      
    • 关键字参数和默认值:调用函数时候,指定哪个形参值是什么,不用考虑位置对齐的问题。

    • 收集参数:星号* 意思是收集其余位置参数放在元组里。
      eg:

      def print_params(title,*params):
         print(title)
         print(params)
      if __name__ == '__main__':
         print_params('Params',1,2,3)
         
      ---> Params
          (1, 2, 3)
      
      • 处理关键字参数的收集:两个 ** 关键字参数放在字典里
        def print_params(**params):
            print(params)
        
        if __name__ == '__main__':
        print_params(x=1,y=2,z=3)
        
  • 递归:

    • 二分(返回序列里第一个等于位置,不存返回None):
       def search(sequence,number,lower=0,upper=None):
          if upper==None: upper=len(sequence)-1
             if upper<lower:
                 if sequence[lower]==number  : return lower
                 else : return None;
         middle=int((lower+upper)/2);
         if sequence[middle]>=number: return search(sequence,number,lower,middle-1);
         else : return search(sequence,number,middle+1,upper);  
      
      非递归版:
         def search2(sequence,number,lower=0,upper=None):
         if upper==None : upper=len(sequence)-1
         while lower<=upper:
             middle=int((upper+lower)/2)
             if sequence[middle]>=number:upper=middle-1;
             else:lower=middle+1
             if sequence[upper+1] != number: return None
             else: return upper+1
      

第七章 更加抽象

  • 创建自己的类:

    class Person:
        def setName(self,name):
            self.name=name
        def getName(self):
            return self.name
        def greet(self):
            print("Hello,world! I'm %s." % self.name)
        def __inaccessible(self):
            print("Bet you cann't see me")
        def accessible(self):
            print("The secret messsage is:")
            self.__inaccessible()
    
    if __name__ == '__main__':
        p1=Person()
        p1.setName('yexiaoju')
        p1.greet()
        p1.accessible()
        p1._Person__inaccessible()
       
    
  • python并不直接支持私有方式,为了让方法或者特性变为私有(从外部无法直接访问),只要在它的名字前面加上双下划线即可。如上面例子。需要访问__inaccessible()方法,得加_类名+方法。

第八章:异常

Python 用异常对象(exception boject)来表示异常情况。遇到错误后,会引发异常。如果异常对象并未被处理或捕捉,程序就会被所谓的回溯终止执行。

  • 捕捉异常(try/except):
while True:
   try:
       x=int(input('Enter the first number:'))
       y=int(input('Enter the second number:'))
       print(x/y)
   except ZeroDivisionError:# 除0异常
       print("The second number can't be zero!")
   except TypeError:#输入类型异常
       print("That wasn't a number !")     
   except:#捕捉所有上面漏掉的异常
       print('There is something wrong!')      

上面例子不止一个except,如果有异常会捕捉对应类型去接受,这里有ZeroDi…和TypeError两种.也可以用一个块去捕捉多个异常。用元组将他们列出:

except(ZeroDivisionError,TypeError,NameError):

就算程序处理好几种类型的异常,但是还是有异常会漏掉,像上面例子最后一个except:没有表明捕捉什么类型异常就是捕捉所有异常。

  • raise 语句:引发异常,可以用一个Exception异常类或者自定义异常来被raise调用。 eg: raise Exception
  • 自定义异常:继承EXception
class MyException(Exception):
    def __init__(self,message):
        Exception.__init__(self)
        self.message=message

if __name__ == '__main__':
    a = int(input("please input a num:"))
    if a < 10:
        try:
            raise MyException("my excepition is raised ")# 引发自定义异常,进入下面的except模块里
        except MyException as e:
            print(e.message)
  • raise 不带参数:相当于没有异常处理,又抛出这个异常信息。
    下面一个例子显示一个switch控制异常是否屏蔽的机制。

    class MufiedCalcul:
      switch=False
      def cal(self,expr):
          try:
              return eval(expr)
          except ZeroDivisionError:
              if self.switch:
                  print("Division by zero is illege")
              else :
                  raise
    
  • 万事大吉(try/except/else):

    • 异常没有发生执行一段代码,可以在后面加一个else。
    • 不知道异常信息也可以打印出来。
 while True:
        try:
            x=int(input('Enter the first number:'))
            y=int(input('Enter the second number:'))
            print(x/y)
        except Exception as e:
            print("Invalid input:",e)
            print("please try again!")
        else:
            print("No Error,Quit!")
            break
  • 最后finally:它可以用来可能的异常后进行清理。

     try:
           1/0;
       except ZeroDivisionError:
           print("Unknow variable")
       else:
           print("That went well")
       finally:
           print("OK?")
    

    不管异常有没有执行,最后finally一定会执行。

  • 异常会递归回溯到直到函数调用的那一层。

  • 异常之禅:有些时候在判断字典或对象是否存在特性时,条件语句可以实现和异常处理一样的功能,两者各有千秋。

第九章:魔法方法,属性和迭代器

  • 构造方法:init()

      class FooBar:
          def __init__(self):
          self.somevar=42;
    
      if __name__ == '__main__':
          b=FooBar()
          print(b.somevar)
    
  • 继承:新的类的构造方法需要初始化父类的构造方法,防止父类有些特性没有继承过来。具体方法使用super函数。

  • Super函数:超类(父类)函数

class Bird:
   def __init__(self):
       self.hungry=True;

   def eat(self):
      if self.hungry== True :
          print('Aaaaah')
          self.hungry=False
      else : print("No,thanks!")

class SongBird(Bird):
   def __init__(self):
       super(SongBird, self).__init__()#super()也可以不带参数
       self.sound="Squawk"
   def sing(self):
       print(self.sound)

if __name__ == '__main__':
    sb=SongBird()
    sb.eat()
    sb.eat()
    sb.sing()
  • 基本序列和映射规则:
    序列和映射是对象的集合,如果对象是不可变那么只有下面前两个魔法,如果可变则可以使用下面四个魔法:

    • __ len__(self): 返回数目
    • __ gettitem__(self.key): 返回键值查询值,每次用索引查询都会调用这个方法
    • __ settitem__(self.key,value): 根据索引属性key设置value
    • __ delitem __(self,key): 删除

    实践,创建一个可以修改的无穷序列。实现了gettitem,settitem两个方法,因为是无穷的没有实现len,del方法,故调用的话就是非法报错。

     def checkIndex(key):
         if not isinstance(key,int): raise TypeError
         if key<0: raise IndexError
    
     class ArithmticSequence:
         def __init__(self,start=0,step=1):
             self.start=start
             self.step=step
             self.changed={}
    
         def __getitem__(self,key):
             checkIndex(key)
             try: return self.changed[key]
             except KeyError: return self.start+key*self.step
    
         def __setitem__(self, key, value):
             checkIndex(key)
             self.changed[key]=value
    
     if __name__ == '__main__':
         s=ArithmticSequence(1,2)
         print(s[4])
         s[4]=1
         print(s[4])
    
    • 子类化列表,字典和字符串:
     class CountList(list):
         def __init__(self,*args):
             super().__init__(*args)
             self.counter=0
         def __getitem__(self, item):
             self.counter+=1
             return super().__getitem__(item)
    
     if __name__ == '__main__':
         c1=CountList(range(10))
         print(c1)
         del(c1[3:6])
         print(c1)
         c1[2]+=c1[4]
         print(c1.counter) 
         
     --------------------------------
     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
     [0, 1, 2, 6, 7, 8, 9]
     2
    
  • property 函数:

    • 将类方法转换为只读属性
    • 重新实现一个属性的setter和getter方法

eg:

class Rectangle:
    def __init__(self):
        self.width=0
        self.height=0
    def setSize(self,size):
        self.width,self.height=size
    def getSize(self):
        return self.width,self.height
    size=property(getSize,setSize)

if __name__ == '__main__':
    r=Rectangle()
    r.width=10
    r.height=5
    print(r.size)
    r.size=150,100
  • 迭代器__ iter__: __ iter__()返回一个迭代器(iterator),所谓迭代器就是具有__ next__(这个方法在调用时不需要任何参数)方法的对象。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引起一个
class Fibs:
    def __init__(self):
        self.a=0
        self.b=1
    def __next__(self):
        self.a,self.b= self.b,self.a+self.b
        return self.a
    def __iter__(self):
        return self

if __name__ == '__main__':
    f=Fibs()
    for i in f:
        if i >1000:
            print(i)
            break

迭代器实现了__ iter__方法,这个方法实际上返回迭代器本身。

  • 从迭代器的到序列:用list构造方法显式的将迭代器转换为列表。
class TestIterator:
    value = 0
    def __next__(self):
        self.value += 1
        if self.value > 10:raise StopIteration
        return self.value
    def __iter__(self):
        return self

if __name__ == '__main__':
    ti=TestIterator()
    print(list(ti))  
  • 生成器: 用普通函数定义的迭代器 yield

    • 这一段初看书,我也不是很懂,知乎上这个回答 不错。

    • 创建生成器:

      def flatten(nested):
        for sublist in nested:
         for element in sublist:
             yield element
      

      if name == ‘main’:
      ​ nested=[[1,2],[3,4]]
      ​ for num in flatten(nested):
      ​ print(num)

      
      
    • 递归生成器:
      ​```python
      def flatten(nested):
      try:
      for sublist in nested:
      for element in flatten(sublist):
      yield element
      except TypeError:
      yield nested

    if name == ‘main’:
    nested=[[1],2,[3,[4]]]]
    for num in flatten(nested):
    print(num)

    
    上面代码有一个问题,如果列表里是字符串对象,那它也是一个序列,是不会出现TypeError,所以修改一下需要对字符串判断。
    
    ```python
    def flatten(nested):
    try:
      try:nested+''
      except:pass
      else :raise TypeError
      for sublist in nested:
          for element in flatten(sublist):
              yield  element
    except TypeError:
       yield  nested
    
    if __name__ == '__main__':
       nested=['123',['yexiaoju'],'memeda']
       for num in flatten(nested):
           print(num)
    
    
  • 通用来说生成器主要是由生成器函数和生成器迭代器组成。

  • 运用生成器编写递归问题:这一块我看了好久,输出中间变量才满满懂了一点。

  def conflict(state,nextX):
    nextY=len(state)
    for i in  range(nextY):
        if abs(state[i]-nextX) in (0,nextY-i):
            return True
    return False

def queens(num,state=()): #运用生成器写(一段递归程序)八皇后问题
    if len(state) ==num-1:
        for pos in range(num):
            if not conflict(state,pos):
                yield (pos,)
    else:
        for pos in range(num):
            if not conflict(state,pos):
             for result in queens(num,state+(pos,)):
                 yield  (pos,)+result

def queens2(num,state=()):#将上面程序稍微简化写法
     for pos in range(num):
        if not conflict(state,pos):
            if len(state)==num-1:
                yield (pos,)
            else:
                for result in queens2(num,state+(pos,)):
                    yield  (pos,)+result

def prettyprint(solution):#将得到的八皇后结果模拟图像形象的输出
    def line(pos,length=len(solution)):
        return '.'*(pos)+'X'+'.'*(length-pos-1)
    for pos in solution:
        print(line(pos))



if __name__ == '__main__':
   print(list(queens(8)))
   print(len(list(queens(8))))
   queens3(8)
   
   import random  
   prettyprint(random.choice(list(queens(8))))
   

第十章:充电时刻

  • 模块:import

    • 使用dir:查看模块包含的内容
    • __ all__():
    • help(): 获取帮助文本
  • 文档:__ doc__ 在线文档:http://python.org/doc

  • 使用源代码: __ file__ eg:print(copy.__ file__)#输出文件本地路径,就可以查看文件代码

  • 标准库:

    • sys: 访问与python解释器联系紧密的变量和函数。
    import sys
    print(' '.join(reversed(sys.argv[1:]))) #反序打印命令行参数
    
    • os:提供访问多个操作系统服务的功能。
    import os
    import webbrowser
    if __name__ == '__main__': #通过命令打开程序
      os.system(r'D:\"CS 1.6"\"CS 1.6"\cstrike.exe') #文件夹名需要" "
      os.startfile(r'D:\CS 1.6\CS 1.6\cstrike.exe') # 接受一般的路径,含有空格也没有关系
      webbrower.open('mryxj.github.io')#启动浏览器打开特定网站             
    
    • fileinput:
  • 集合:set():

  • 堆:heapq()

    • heappush(heap,x):将x入堆
    • heappop(heap):将堆中最小的元素弹出
    • heapreplace(heap,x) :将堆中最小元素弹出,并将x入堆
    • nlargest(n,iter): 返回iter中第n大的数
    • nsamallest(n,iter):返回iter中第n小的数
     from heapq import *
     from random import shuffle
     data=[1,2,3,4,5,6,7,8,9,10]
     shuffle(data)
     heap=[]
     for n in data:
       heappush(heap,n)
     heappush(heap,0.5)
     print(heap)
     
     ----> [0.5, 1, 2, 5, 3, 4, 9, 10, 8, 7, 6]
    
  • 双端队列:

    • append(x):右端增加一个元素x
    • appendleft(x):左端增加一个元素x
    • popleft(x): 左端删除一个元素x
    • roate(x):将右边前x个元素整体移到左端
    from collections import deque
    q=deque(range(5))
    q.append(5)
    q.appendleft(6)
    
    
  • time:获取当前时间,操作时间和日期。

  • random:

    • random(n):返回[0,n)之间随机数
    • getrandbits(n):以长整型形式返回n个随机数
    • uniform(a,b):返回随机数n,a<=n<b
    • randrange():
    • choice(seq):从序列seq中返回随意元素
    • shuffile(seq[,random]):

猜你喜欢

转载自blog.csdn.net/yexiaohhjk/article/details/87889195