zoukankan      html  css  js  c++  java
  • python之路-基础篇-第三周


    〇、上集回顾

    字符编码:ascii-unicode-utf8

    传入参数:sys模块,与python解释器相关

    字符串相加,字符串本质是c数组,在内存中为连续的空间

    基本数据类型:一切事物都是对象,对象都由类创建,对象的方法都是类中成员

    int、str、tuple、list、dict


    一、集合:set

    元组和列表中的元素可以重复,set中不允许

    可以作为爬虫缓存使用

    优势:

    • 访问速度快

    • 原生解决去重问题

    新建set或者更新set

    
    >>> s1 = set()    #创建一个新的set
    
    >>> s1.add('alex')    #增加一个元素
    
    >>> print(s1)
    
    {'alex'}
    
    >>> s1.update(['alex','eric'])    #增加多个元素
    
    >>> print(s1)
    
    {'eric', 'alex'}
    
    

    差集:

    
    >>> s2 = set(['alex','alex'])
    
    >>> s2
    
    {'alex'}
    
    >>> s2 = set(['alex','alex','eric','tony'])
    
    >>> s2
    
    {'eric', 'tony', 'alex'}
    
    >>> s3 = s2.difference(['alex','eric'])        #检查差异,生成了一个新的set
    
    >>> s3
    
    {'tony'}
    
    >>> s2.difference(['alex','eric'])
    
    {'tony'}
    
    >>> s2
    
    {'eric', 'tony', 'alex'}
    
    >>> s4 = s2.difference_update(['alex','eric'])   #检查差异,修改原来的set
    
    >>> s4
    
    >>> s2
    
    {'tony'}
    
    

    取交集

    
    >>> s1 = set([11,22,33,44])
    
    >>> s2 = set([33,44,55])
    
    >>> s3 = s1.intersection(s2)    #取交集,形成一个新的set,如&运算符
    
    >>> s3
    
    {33, 44}
    
    >>> s1
    
    {33, 11, 44, 22}
    
    >>> s4 = s1.intersection_update(s2)    #取交集,更新原来的set
    
    >>> s4
    
    >>> s1
    
    {33, 44}
    
    >>> s1.isdisjoint(s2)    #是否有交集,没有交集返回True,有交集返回False
    
    False
    
    >>> 
    

    子集或父集

    >>> s1
    
    {33, 44}
    
    >>> s2
    
    {33, 44, 55}
    >>> s1.issubset(s2)    #是否为子集(包含于),是返回True
    
    True
    
    >>> s2.issuperset(s1)   #是否为父集(包含),是返回True,
    
    True
    
    >>> 
    

    移除:

    pop #将删除的作为返回值
    remove #无返回值

    >>> s1
    
    {33, 44}
    
    >>> s2
    
    {33, 44, 55}
    
    >>> s3 = s1.pop()   #随机删除一个值,并返回这个值
    
    >>> s3        #这里删除了‘33’
    
    33
    
    >>> s1        #
    
    {44}
    
    >>> s4 = s2.remove(33)    #指定删除某个元素,不返回值
    
    >>> s4  #返回值为空
    
    >>> s2
    
    {44, 55}
    
    
    

    对称差集与并集

    
    
    ret1 = s1.difference(s2)    
    
    ret2 = s1.symmetric_difference(s2)   
    >>> s1 = set([11,22,33])
    
    >>> s2 = set([22,44])
    
    >>> ret1 = s1.difference(s2)  #差集,返回不包含与s2中的s1元素,等价于s1-s2
    
    >>> ret1
    
    {33, 11}
    
    >>> s1-s2
    
    {33, 11}
    
    >>> ret2 = s1.symmetric_difference(s2) #对称差集,返回两个set中不同元素的合集,等价于(s1|s2)-(s1&s2)
    
    >>> ret2
    
    {33, 11, 44}
    
    >>> (s1|s2)-(s1&s2)
    
    {33, 11, 44}
    
    >>> ret3 = s1.union(s2)  #求并集,等价于s1|s2
    
    >>> ret3
    
    {33, 11, 44, 22}
    
    >>> s1|s2
    
    {33, 11, 44, 22}
    

    简单的例子(寻找差异):

    
    # 数据库中原有
    old_dict = {
        "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 },
        "#2":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 },
        "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 }
    }
      
    # cmdb 新汇报的数据
    new_dict = {
        "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 800 },
        "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 },
        "#4":{ 'hostname':c2, 'cpu_count': 2, 'mem_capicity': 80 }
    }
    
    - 需求:
        1.原来没有的-新增
        2.原有有的-更新
        3.原来有的新的没有-原来删除
    - 结果:
    
        1. 要更新的数据
    
        2. 要删除的数据
    
        3. 要增加的数据
    
    

    代码:

    
    # 数据库中原有
    old_dict = {
        "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 },
        "#2":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 },
        "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 }
    }
      
    # cmdb 新汇报的数据
    new_dict = {
        "#1":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 800 },
        "#3":{ 'hostname':c1, 'cpu_count': 2, 'mem_capicity': 80 },
        "#4":{ 'hostname':c2, 'cpu_count': 2, 'mem_capicity': 80 }
    }
    
    s1 = set(old_dict.keys())
    s2 = set(new_dicr.keys())
    #取交集,可能要更新,可能不动
    s3 = s1.intersection(s2)
    #删除的元素,
    s4 = s1.difference(s2)
    #增加的元素
    s5 = s2.difference(s1)
    
    

    可以用方法实现,也可以使用运算符来实现

    
    
    
    >>> s1 = set([1,2,3])
    
    >>> s2 = set([1,3,4])
    
    >>> #取交集,可能要更新,可能不动
    
    ... s3 = s1.intersection(s2)
    
    >>> #删除的元素,
    
    ... s4 = s1.difference(s2)
    
    >>> #增加的元素
    
    ... s5 = s2.difference(s1)
    
    >>> s3
    
    {1, 3}
    
    >>> s4
    
    {2}
    
    >>> s5
    
    {4}
    
    >>> 
    
    >>> s1|s2
    
    {1, 2, 3, 4}
    
    >>> s1 & s2
    
    {1, 3}
    
    >>> s1 - s2
    
    {2}
    
    >>> s2 -s1
    
    {4}
    
    >>> 
    
    

    二、collections系列

    使用需要导入,import collections

    1、counter:继承dict,计数器

    
    import collections
    c1 = collections.Counter('asdcasdqasdaacasaasasdqqasd')
    print(c1)
    c2 = c1.most_common(4) #前四位
    print(c2)
    # for i in c1.elements(): #print 所有对象,原生的值
    #     print(i)
    
    c3 = dict(c1)  #转化为字典
    print(c3)
    
    for k,v in c1.items():  #计数器也具备dict的方法items,keys,values,
        print(k,v)    #循环的处理完后的数据
    
    
    
    
    执行结果:
    
    Counter({'a': 10, 's': 7, 'd': 5, 'q': 3, 'c': 2})  #奇怪的对象
    
    [('a', 10), ('s', 7), ('d', 5), ('q', 3)]
    
    {'c': 2, 'd': 5, 'a': 10, 'q': 3, 's': 7}
    
    c 2
    
    d 5
    
    a 10
    
    q 3
    
    s 7
    
    

    fromkeys #这个方法没有定义,忽略

    
    import collections
    obj = collections.Counter([11,22,22,33,44])
    print(obj)
    obj.update([11,'eric'])
    print(obj)
    obj.subtract([55,11])    #delete,会出现-1
    print(obj)
    执行结果:
    
    Counter({22: 2, 33: 1, 11: 1, 44: 1})
    
    Counter({11: 2, 22: 2, 33: 1, 'eric': 1, 44: 1})
    
    Counter({22: 2, 33: 1, 'eric': 1, 11: 1, 44: 1, 55: -1})
    
    

    2、有序字典(OrderedDict)

    如何实现一个有序的字典,可以使用一个原有的无序字典+一个列表,使用列表来维护key

    3、默认字典(defaultdict)

    defaultdict是对字典的类型的补充,他默认给字典的值设置了一个类型。

    
    import collections
    obj2 = collections.defaultdict(list)
    obj2['k1'].append('v1')
    print(obj2)
    执行结果:
    
    defaultdict(<class 'list'>, {'k1': ['v1']})
    
    

    4、可命名元组

    根据nametuple可以创建一个包含tuple所有功能以及其他功能的类型。

    
    
    
    import collections
    MyTupleClass = collections.namedtuple('MyTupleClass', ['x', 'y', 'z'])
    obj = MyTupleClass(11, 22, 33)
    print(obj.x,obj.y,obj.z)
    执行结果:
    
    11 22 33
    
    

    5、队列

    双向队列:首尾可取可放

    
    import  collections
    obj = collections.deque()
    obj.append('1')
    obj.appendleft('2')
    obj.append('1')
    print(obj)
    c = obj.count('1')
    print(c)
    obj.extend(['2','2'])
    obj.extendleft(['1','2'])
    print(obj)
    执行结果:
    deque(['2', '1', '1'])
    2
    deque(['2', '1', '2', '1', '1', '2', '2'])
    
    

    单向队列:先进先出

    
    import queue
    q = queue.Queue()
    # q.qsize()
    # q.full()
    q.put('1')
    print(q.get())
    执行结果:
    
    1
    
    

    三、深浅拷贝

    
    #导入模块
    
    import copy
    
    #浅拷贝,更加节约内存
    
    copy.copy()
    
    #深拷贝
    
    copy.deepcopy()
    
    

    针对数字和字符串:深拷贝和浅拷贝都不会改变内存ID

    
    >>> a = 123
    
    >>> b = 123
    
    >>> id(a),id(b)    #缓存
    
    (4297541856, 4297541856)
    
    >>> import copy
    
    >>> b = copy.copy(a)    #浅拷贝没有改变内存ID
    
    >>> id(a),id(b)
    
    (4297541856, 4297541856)
    
    >>> c = copy.deepcopy(a)    #深拷贝也没有改变内存ID
    
    >>> id(a),id(c)
    
    (4297541856, 4297541856)
    
    

    针对其他类型:如字典,列表中的多层嵌套,浅拷贝和深拷贝将有所不同

    
    >>> n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
    
    >>> n2 = n1
    
    
    
    >>> id(n1),id(n2)        #两个字典指向同一个ID
    
    
    
    (4303008072, 4303008072)
    
    >>> n3 = copy.copy(n1)    #浅拷贝
    
    >>> id(n1),id(n3)        #字典的id已经不同,说明浅拷贝开辟了新的内存空间
    
    (4303008072, 4312709384)
    
    >>> id(n1['k3'])        #但是字典中的列表ID还是没有改变,说明对字典中的列表没有作拷贝
    
    4313460872
    
    >>> id(n3['k3'])
    
    4313460872
    
    >>> n4 = copy.deepcopy(n1)    #深拷贝
    
    >>> id(n1),id(n4)            #字典的id已经不同,说明深拷贝开辟了新的内存空间
    
    (4303008072, 4312707144)
    
    >>> id(n4['k3'])            #字典中的列表也已经改变,说明深拷贝针对字典中的列表也进行了拷贝
    
    4313524744
    
    >>> id(n1['k3'])
    
    4313460872
    
    >>> 
    
    

    深拷贝和浅拷贝的区别,以服务器监控模板的拷贝为例:

    
    
    
    import copy
    dic = {
        'cpu':[80,],
        'mem':[80,],
        'disk':[80,]
    }
    new_dic = copy.copy(dic)
    new_dic['cpu'][0] = 50
    print(dic)
    print(new_dic)
    
    执行结果:
    
    {'cpu': [50], 'disk': [80], 'mem': [80]}
    {'cpu': [50], 'disk': [80], 'mem': [80]}
    
    
    
    import copy
    dic = {
        'cpu':[80,],
        'mem':[80,],
        'disk':[80,]
    }
    new_dic = copy.deepcopy(dic)
    new_dic['cpu'][0] = 50
    print(dic)
    print(new_dic)
    
    
    执行结果:
    
    {'cpu': [80], 'disk': [80], 'mem': [80]}
    
    {'cpu': [50], 'disk': [80], 'mem': [80]}
    
    

    四、函数

    1、函数的定义和使用

    函数的定义主要有如下要点:

    • def:表示函数的关键字

    • 函数名:函数的名称,日后根据函数名调用函数

    • 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...

    • 参数:为函数体提供数据

    • 返回值:当函数执行完毕后,可以给调用者返回数据。

    
    def mail():
        n = 123
        n += 1
        print(n)
    
    mail()            #执行函数
    f = mail        #内存地址指向f
    f()            #同样可以执行函数
    执行结果:
    
    124
    
    124
    
    

    1)返回值

    return

    • 返回值,返回啥都行,如果没有使用return默认返回None
    
    #举例:发送邮件
    
    import smtplib
    from email.mime.text import MIMEText
    from email.utils import formataddr
    def mail():
        ret = True
        try:
            msg = MIMEText('邮件内容', 'plain', 'utf-8')
            msg['From'] = formataddr(["武沛齐",'wptawy@126.com'])
            msg['To'] = formataddr(["走人",'389285205@qq.com'])
            msg['Subject'] = "主题"
    
            server = smtplib.SMTP("smtp.126.com", 25)
            server.login("wptawy@126.com", "邮箱密码")
            server.sendmail('wptawy@126.com', ['389285205@qq.com',], msg.as_string())
            server.quit()
        except Exception:
            ret = False
        return ret    #返回值
    
    ret = mail()
    if ret:
        print('发送成功')
    else:
        print('发送失败')
    
    • 遇到return,函数结束不再执行,中断函数操作
    
    #举例:(使用pycharm的断点调试)
    
    
    
    def show():
        print('a')
        if 1 == 1:
            return [11,22]    #中断函数
        print('b')
    ret = show()
    

    2)参数

    
    #没有参数
    def show():
        print('a')
    show()
    
    #两个参数
    def show1(a,b):
        print(a,b)
    show1(1,2)
    
    #默认参数,必须写在后面
    def show2(a,b=200):
        print(a,b)
    show2(100)
    show2(100,180)
    
    #指定参数
    def show3(a,b):
        print(a,b)
    show3(b=100,a=200)
    

    函数使用动态参数:

    
    def show1(*args):            #转化为元组
        print(args,type(args))
    show1(11,22,33,44,55,212)
    
    def show2(**kwargs):        #转化为字典
        print(kwargs,type(kwargs))
    show2(n1 = 123,n2 = 32)
    
    def show3(*args,**kwargs):    #编写有顺序,传入参数时候也有顺序
        print(args,type(args))
        print(kwargs,type(kwargs))
    show3(11,22,3,4,55,n1=23,n2=123)
    执行结果:
    
    (11, 22, 33, 44, 55, 212) <class 'tuple'>
    
    {'n1': 123, 'n2': 32} <class 'dict'>
    
    (11, 22, 3, 4, 55) <class 'tuple'>
    
    {'n1': 23, 'n2': 123} <class 'dict'>
    
    
    
    def show3(*args,**kwargs):
        print(args,type(args))
        print(kwargs,type(kwargs))
    show3(11,22,3,4,55,n1=23,n2=123)
    #另外一种方法传入多个参数
    l = [11,22,3,4,55]
    d = {'n1':23,'n2':123}
    show3(*l,**d)
    执行结果:完全一致
    
    (11, 22, 3, 4, 55) <class 'tuple'>
    
    {'n1': 23, 'n2': 123} <class 'dict'>
    
    (11, 22, 3, 4, 55) <class 'tuple'>
    
    {'n1': 23, 'n2': 123} <class 'dict'>
    
    

    字符串格式化format使用这个方式

    
    s1 = '{0} is {1}'
    l = ['alex','sb']
    #result = s1.format('alex','sb')
    result = s1.format(*l)
    print(result)
    
    s2 = '{name} is {actor}'
    d = {'name':'alex','actor':'sb'}
    #result = s2.format(name='alex',actor='sb')
    result = s2.format(**d)
    print(result)
    

    2、匿名函数

    简单函数,只用一行来表示。也叫lambda表达式,lambda存在意义就是对简单函数的简洁表示

    
    #lambda 表达式
    func = lambda a:a+1
    # 创建形式参数:a
    # 函数内容:a+1 返回结果a+1
    ret = func(999)
    print(ret)
    
    
    执行结果:
    
    1000
    
    

    3、内置函数

    随便说几个。。。

    
    abs()    #绝对值
    
    dict()    #字典
    
    help()    #帮助
    
    min()    #求最小值
    
    setattr()    
    
    all()    #循环列表,如果列表中所有值均为真,返回真
    
    dir()    #查看类方法
    
    hex()    #16进制
    
    next()    
    
    slice()    #切片
    
    any()    #循环列表,如果列表中只要有一个真,返回真
    
    divmod()    #地板除
    
    id()    #查看内存地址
    
    object()    
    
    sorted()    #排序
    
    ascii()    #ascii(9)等价于 int.__repr__(9),并得到返回值
    
    enumerate()    #给序列增加一个序号,额外增加一列
    
    input()    #输入,等价于python2.x中raw_input
    
    oct()    #八进制
    
    staticmethod()    #静态方法
    
    bin()    #返回二进制数
    
    eval()    #将字符串用表达式执行,返回结果eval('6*8')->48
    
    int()    #转化为int类型
    
    open()    #打开文件
    
    str()    #转化为字符串类型
    
    bool()    #返回bool值
    
    exec()    
    
    isinstance()        #判断类型的方法
    
    sum()    #求和
    
    bytearray()    #返回字节数组
    
    filter()    #过滤部分成员
    
    issubclass()    
    
    pow()    #幂
    
    super()    #父类
    
    bytes()    #返回字节
    
    float()    #转化为浮点数
    
    iter()    
    
    print()    #打印
    
    tuple()    #转化为元组
    
    callable()    #是否可执行,能够被调用返回True,即类中有__call__方法
    
    format()    
    
    len()    #求长度
    
    property()    
    
    type()    #类型
    
    chr()    #ascii码数字转化为字符
    
    ord()    #字符转化为ascii码数字
    
    frozenset()    #不能增加和修改的集合
    
    list()    #转化为列表
    
    range()    #拿到数的区间,等同于python2.x的xrange()
    
    vars()    #返回dir()中对应的值
    
    classmethod()    #类方法
    
    getattr()    
    
    locals()    #局部变量
    
    repr()    #调用__repr__
    
    zip()    #
    
    compile()    #编译。。。
    
    globals()    #返回当前所有可用的变量
    
    map()    #针对每个成员执行
    
    reversed()    #翻转
    
    __import__()    
    
    complex()    #复数
    
    hasattr()    
    
    max()    #求最大值
    
    round()    #四舍五入
    
    delattr()    
    
    hash()    #哈希,如果字典中的字符串太大,通过hash来计算下,节约内存空间
    
    memoryview()    
    
    set()    #集合
    
    
    
    li = ['a','b','c']
    for i,item in enumerate(li,1):
        print(i,item)
    执行结果:
    
    1 a
    
    2 b
    
    3 c
    
    
    
    >>> all(['1','s',1,2,''])
    
    False
    
    >>> any([[],(),{},'',0,1])
    
    True
    
    

    4、open函数

    open函数是打开文件的重要函数。

    
    f = open('text.txt', 'r', encoding='utf-8')
    ret = f.read(4)  #安装字符来读的,python3.x
    ret2 = f.tell()  #按照字节来获取指针位置
    f.close()
    print(ret)
    print(ret2)
    
    f = open('text.txt', 'r', encoding='utf-8')
    f.seek(3)    #跳到指针位置,如果是1或者2的话会报错(一个汉字三个字节)
    ret = f.read()
    f.close()
    print(ret)
    
    f = open('text.txt', 'r+', encoding='utf-8')
    f.seek(3)
    f.truncate()  #删除指针后面的所有字符,然后保存到文件中
    f.close()
    
    执行结果:
    
    二asd
    
    6
    
    asdasdasdasdasdasd
    
    

    五、作业:修改配置文件

    1、用户输入字符串

    ‘{"backend": "test.oldboy.org","record":{"server": "100.1.7.999","weight": 20,"maxconn": 30}}’

    2、将用户输入的字符串转换为字典

    s = input('input your text:')

    import json

    dic = json.loads(s)

    3、添加到行后面

    4、删除【可选】

    5、不存在如何???【可选】

    http://www.cnblogs.com/wupeiqi/articles/4950799.html

  • 相关阅读:
    WinEdt && LaTex(五)—— 内容的排版
    WinEdt && LaTex(五)—— 内容的排版
    WinEdt && LaTex(四)—— 自定义新命令(newcommand、def)
    WinEdt && LaTex(四)—— 自定义新命令(newcommand、def)
    独立与条件独立
    “人”之为人:道德+技能+创新
    android之ListPreference的用法_PreferenceActivity用法
    【Oracle】删除重复记录
    wso2esb源码编译总结
    .net网站开发(设计):1.什么是MVC模式
  • 原文地址:https://www.cnblogs.com/felo/p/5143430.html
Copyright © 2011-2022 走看看