• Python 学习拾遗


    该博文主要适应于python2.7,并没有对py3进行测试。

    主要记录学习python过程中容易出现的一些小问题、小错误,相信能给你启发。

    1、剔除一个字符串中的所有空格(假设该字符串是s)

    "".join(s.split())

    样例输入:

    s = '    123  4567    8   '

    样例输出:

    '12345678'

     

    2、剔除文件名字符串中的非法字符(假设字符串是s)

    有的时候从网上抓取下来的标题需要作为文件名保存到本地(windows环境)

    但是windows下文件名中不能包含一些非法字符,例如‘/’、‘’、‘?’ 神马的

    你可以用下面这段代码剔除标题中的非法字符

     

    pattern = re.compile(r'[/:*?"<>|]')
    s = re.sub(pattern,'',s)

    样例输入:

    s = '<<?I am title?>>'

    样例输出:

    'I am title'

     

    3、列表解析、base64解密、chr()、int()、join()函数使用

    这是知道创宇的余弦出的一个解密小游戏,给你一个字符串,你需要解密出一个邮箱地址。

    密码字符串为:

    XDY1XDc2XDY5XDZjXDYzXDZmXDczXDQwXDY3XDZkXDYxXDY5XDZjXDJlXDYzXDZmXDZk

    解密方式为先用base64解密,再进行16进制转换,最后按ASCII码输出每个字符。

    这个小游戏很有意思,可以学习到一些python知识。

    下面是解题步骤:

    1、base64解密

    s = 'XDY1XDc2XDY5XDZjXDYzXDZmXDczXDQwXDY3XDZkXDYxXDY5XDZjXDJlXDYzXDZmXDZk'

    print base64.b64decode(s)

    输出:

    6576696c636f7340676d61696c2e636f6d

    这一看就是一种字符编码,最先猜到是ASCII编码。

    为了方便观察,将其拆分:

    print base64.b64decode(s).split('\')

    输出:

    ['', '65', '76', '69', '6c', '63', '6f', '73', '40', '67', '6d', '61', '69', '6c', '2e', '63', '6f', '6d']

    由于每个元素带有字母,猜测是16进制数,转换进制。

    int(c,16) 可以将字符串c当成16进制数,将其转换成10进制数返回(注意返回的是一个整数)

    chr(n)     可以将一个整数n转换成对应的ASCII字符。

    于是有代码:

    for c in base64.b64decode(s).split('\'):
      if c:   # 剔除空元素
        print chr(int(c,16)),

    输出:

    e v i l c o s @ g m a i l . c o m 

    以上代码可以用 列表解析 简洁表示:

    print [chr(int(c,16)) for c in base64.b64decode(s).split('\') if c]

    输出:

    ['e', 'v', 'i', 'l', 'c', 'o', 's', '@', 'g', 'm', 'a', 'i', 'l', '.', 'c', 'o', 'm']

    3、join()连接为字符串

    s.join(l)  表示将列表l中每个字符连接成一个字符串,用字符串s作为间隔

    so,可以将上述列表连接成字符串:

    print ''.join([chr(int(c,16)) for c in base64.b64decode(s).split('\') if c])

    输出:

    evilcos@gmail.com

    以上,就得到余弦大大的邮箱咯,是不是很有意思?

     

    4.理解python继承的小例子

     1 #coding=gbk
     2 class A(object):
     3     name = 'boss'
     4     print name
     5     def __init__(self,name=None):
     6         print '2'
     7         if name is not None:
     8             self.name = name
     9         print self.name
    10 
    11 
    12 class B(A):
    13     print '1'
    14     name = 'Boss'
    15 
    16 te = B()

    运行结果:

    boss
    1
    2
    Boss

    可以看出类中变量和函数的继承调用关系。

    实例化B,先是运行从A继承来的语句,运行结果:

    boss

    再运行B中的语句,运行结果:

    1

    最后调用从A继承过来的构造函数__init__(),运行结果:

    2
    Boss

     

    5.python列表解析中的双重循环

    如何将B列表中的每一个元素与A列表中的元素相加,生成一个新列表?

    请看以下代码:

    1 A = [1,2,3]
    2 B = [4,5,6]
    3 print [x+y for x in A for y in B]

    以上列表解析的写法相当于一个双重循环,先遍历B中每一个元素,再遍历A中每一个元素,每轮循环进行元素相加操作,最后得到一个新列表。

     

    6.max()的比较函数

    max()函数原型:

    max(arg1, arg2, *args[, key]) 

    例子:

    1 #coding=gbk
    2 A = [1,3,5,2,4]
    3 
    4 print max(A)                #  输出A中最大的元素
    5 print max(A,key=lambda x:x>2)    # 输出A中第一个大于2的元素
    6 
    7 print max('af', 'be','cd')       # 输出最大的字符串,比较规则为默认的字符串比较规则
    8 print max('af', 'be','cd', key=lambda x: x[1])  # 输出第二个字符最大的字符串

    输出:

    5
    3
    cd
    af

    key参数值为一个函数入口指针,你可以将自己定义的函数作为参数传进来,max函数将根据你定义的函数来进行比较,你可以自己制订比较规则。

    lambda为python中一种定义函数(匿名函数)的方法,你也可以用def定义。

     

    7.reverse()函数有返回值吗?

    请看以下代码,猜猜它会输出什么呢?

    1 A = [1,2,3]
    2 print A.reverse()

    是不是第一眼以为会输出 [3,2,1] ?哈哈,错了。真正的输出是:

    None

    看一下reverse()的语法:

    list.reverse()
    参数:NA
    返回值:该方法没有返回值,但是会对列表的元素进行反向排序。

     

    8.提取url中的host(域名)

    使用urllib库提供的函数,用法如下:

     1 import urllib  
     2   
     3 protocol, rest = urllib.splittype('https://www.cnblogs.com:80/yym2013')  
     4 # protocol : https
     5 # rest     : //www.cnblogs.com:80/yym2013
     6   
     7 host, rest =  urllib.splithost(rest)  
     8 # host : www.cnblogs.com:80
     9 # rest : /yym2013
    10   
    11 host, port = urllib.splitport(host)  
    12 # host : www.cnblogs.com
    13 # port : 80

    参考自: python 获取url的host

     

    9.if-else 单行书写方法

    if a>b:
        t = a
    else:
        t = b

     转换成if-else单行形式:

    t = a if a>b else b

     

    10.open的文件打开模式

    r或rt 默认模式,文本模式读
    rb   二进制文件
      
    w或wt 文本模式写,打开前文件存储被清空
    wb  二进制写,文件存储同样被清空
      
    a  追加模式,只能写在文件末尾
    a+ 可读写模式,写只能写在文件末尾
      
    w+ 可读写,与a+的区别是要清空文件内容
    r+ 可读写,与a+的区别是可以写到文件任何位置

    特别注意:a+、w+、r+的区别,他们虽然都是读写模式,但使用效果是有差别的。

    参考自:Python open()文件处理使用介绍

     

    11.关于文件读写错误 IOError: [Errno 0] Error

      该错误通常在windows环境下,使用a+读写模式打开文件,并对其先进行read()读操作,然后进行write()写入操作后出现的。原因是没有进行flush或者seek等操作,python不知道文件位置在哪了。

    参考自:python IOError: [Errno 0] Error - freeDynasty

     

    12、使用python发送邮件

    参考自:使用python发送邮件

     

    13、python的编号迭代

    有时候想用下标记录当前遍历的位置,同时又想有当前元素,自建一个变量变量作为下标又太low,优雅一些的做法是用内建函数enumerate()进行迭代。

    这样既会有下标,又会有当前迭代元素。

    for index,s in enumerate(str):
        print '%d==>%s'%(index,s)

     

    14、list元素去重

    我比较喜欢用set集合进行去重,另外如果要保留list的顺序的话,需要使用sort进行排序。

    详见:python中对list去重的多种方法

    15、如何用尽量简洁的代码输出一个列表(list)的前五个元素

    最直观的写法,定义一个下标变量index来控制输出:

    1 li = [1,2,3,4,5,6,7,8,9,10]
    2 index = 0
    3 for x in li:
    4     if index>=5:
    5         break
    6     print x
    7     index+=1

    观察代码,发现下标index可以用enumerate函数直接分离出来:

    1 li = [1,2,3,4,5,6,7,8,9,10]
    2 for index,x in enumerate(li):
    3     if index>=5:
    4         break
    5     print x

    还有更简单的写法,使用列表的切片操作来简化代码:

    1 li = [1,2,3,4,5,6,7,8,9,10]
    2 for x in li[:5]:
    3     print x

     

    16、readlines()会读入换行符!

    在一次用smtp服务发送邮件给自己的时候,我用readlines()读取本地文件。

    将带有email的username和password的那两行行直接赋值给用户名和密码变量。

    结果导致收到的邮件开头带有乱码,检查了各个地方都没有发现bug在哪里。

    最后找到原因是输入的用户名和密码最后分别带有一个换行符,而邮件将多余的内容作为乱码来处理了。

    解决方法是readlines()读取每一行内容后,赋值的时候需要先strip()去除字符串前后端多余的空白符。

     

    Freecode# : www.cnblogs.com/yym2013

  • 相关阅读:
    装饰器的应用
    绑定路由关系
    基本使用
    numpy多项式拟合
    pandas空值处理与插值
    索引
    事务
    子查询
    视图
    自关联
  • 原文地址:https://www.cnblogs.com/yym2013/p/5923953.html
Copyright © 2020-2023  润新知