Python 进阶(下)

1、如何调整字符串中文本的格式?

方法:使用 re.sub 
In [113]: import re
In [111]: day = '2017-07-24'
In [115]: re.sub('(\d{4})-(\d{2})-(\d{2})',r'\2/\3/\1',day)
Out[115]: '07/24/2017'

2、如何将多个小字符串拼接成一个大字符串?

方法一:使用 “+” 操作符
In [118]: s = ['sdfdsfs','sdfewv','cvxbxcz','yetruywow'] 
In [119]: string = ''                                    
In [120]: for st in s:                                   
     ...:     string+=st                                 
     ...:     print string
sdfdsfs                                                  
sdfdsfssdfewv                                            
sdfdsfssdfewvcvxbxcz                                     
sdfdsfssdfewvcvxbxczyetruywow  # 此方法会有较大的内存消耗
方法二:使用 str.join 
In [118]: s = ['sdfdsfs','sdfewv','cvxbxcz','yetruywow']
In [121]: ''.join(s)
Out[121]: 'sdfdsfssdfewvcvxbxczyetruywow'
In [122]: s1 = ['dsd','adev',6545,7711,'ewrewc']
In [123]: ''.join((str(x) for x in s1)) # 对有数字的列表进行处理
Out[123]: 'dsdadev65457711ewrewc'

3、如何对字符串进行左、右、居中对齐?

方法一:使用 str.ljust,str.rjust,str.center 
In [124]: s = 'going'
In [125]: s.ljust(20,'-')
Out[125]: 'going---------------'
In [126]: s.rjust(20,'-')
Out[126]: '---------------going'
In [127]: s.center(20,'-')
Out[127]: '-------going--------'
In [133]: d = {'housename':'marryCenter','width':30,'height':20.55,'long':30}
In [137]: for k in d:
     ...:     print k.ljust(max(map(len,d.keys()))),':',d[k]
width     : 30
housename : marryCenter
long      : 30
height    : 20.55
方法二:使用 format 
In [130]: format(s,'<20')
Out[130]: 'going               '
In [131]: format(s,'>20')
Out[131]: '               going'
In [132]: format(s,'^20')
Out[132]: '       going        '

4、如何去掉字符串中不需要的字符?

方法一:使用 strip 
In [145]: s = '///abc*****'
In [148]: s.strip('/*')
Out[148]: 'abc'
方法二:切片拼接
In [149]: s = 'carry?me'
In [151]: s[:5]+s[6:]
Out[151]: 'carryme'
方法三:使用 str.replace 
In [152]: s = 'sweep\nhouse\n'
In [154]: s.replace('\n','')
Out[154]: 'sweephouse'
方法四:使用 re.sub
In [158]: s = 'oh\tmy\ngod'
In [159]: re.sub('[\t\n]','',s)
Out[159]: 'ohmygod'
方法五:使用 str.translate
In [165]: s = 'not\na\tfellower\r'
In [167]: s.translate(None,'\t\r\n')
Out[167]: 'notafellower'

5、如何派生内置不可变类型并修改实例化行为?

方法:实现 __new__ 方法 
例子:将列表中的数字筛选出来。
In [6]: class IntTuple(tuple):
   ...:     def __new__(cls,iterable):
   ...:         l = (x for x in iterable if isinstance(x,int))
   ...:         return super(IntTuple,cls).__new__(cls,l)
   ...:     def __init__(self,iterable):
   ...:         super(IntTuple,self).__init__(iterable)
In [7]: t = IntTuple([1,0,-1,7,'HAH'])   
In [8]: print t                          
(1, 0, -1, 7)
tips:实例由内置方法__new__创建,所以修改__new__方法就可实现新型元组。

6、如何为创建大量实例节省内存?

方法:定义类的__slot__属性
例子:定义一个学生类的两种方法
In [12]: class Student1(object):
    ...:     def __init__(self,mid,name,age,sex):
    ...:         self.mid = mid
    ...:         self.name = name
    ...:         self.age = age
    ...:         self.sex = sex
In [13]: class Student2(object):   # 多了一个__slots__属性
    ...:     __slots__ = ['mid','name','age','sex']
    ...:     def __init__(self,mid,name,age,sex):
    ...:         self.mid = mid
    ...:         self.name = name
    ...:         self.age = age
    ...:         self.sex = sex
In [14]: s1 = Student1('01','kim','20','male')
In [16]: s2 = Student2('01','kim','20','male')
In [21]: set(dir(s1)) - set(dir(s2)) 
Out[21]: {'__dict__', '__weakref__'}# Student1比Student2多出两个属性,所以内存占用方面会比较大
In [23]: s1.email = '[email protected]'  # Student1支持动态绑定
In [24]: s1.__dict__
Out[24]:
{'age': '20',
 'email': '[email protected]',
 'mid': '01',
 'name': 'kim',
 'sex': 'male'}
In [28]: s2.email = '[email protected]'  # Student2不支持动态绑定
AttributeError: 'Student2' object has no attribute 'email'
tips:__slots__属性可以节省__dict__属性,并且不支持动态绑定,从而达到减少内存开销的目的。

7、如何让类支持比较操作?

方法一:类内部实现__lt__,__le__,__gt__,__ge__,__eq__, __ne__
In [36]: class Rectangle(object):
    ...:     def __init__(self,width,height):
    ...:         self.width = width
    ...:         self.height = height
    ...:     def area(self):
    ...:         return self.width*self.height
    ...:     def __gt__(self,obj):  # 大于
    ...:         print '__gt__'
    ...:         return self.area() > obj.area()
    ...:     def __eq__(self,obj):  # 等于
    ...:         print '__eq__'
    ...:         return self.area() == obj.area()
In [37]: r1 = Rectangle(5,5)
In [38]: r2 = Rectangle(4,6)
In [39]: r1 > r2
__gt__
Out[39]: True 
In [40]: r1 == r2
__eq__
Out[40]: False
方法二:使用 total_ordering 简化
In [43]: from functools import total_ordering        
In [44]: @total_ordering                             
    ...: class Rectangle(object):                    
    ...:     def __init__(self,width,height):        
    ...:         self.width = width                  
    ...:         self.height = height                
    ...:     def area(self):                         
    ...:         return self.width*self.height       
    ...:     def __lt__(self,obj):    # 小于           
    ...:         print '__lt__'                      
    ...:         return self.area() < obj.area()     
    ...:     def __eq__(self,obj):     # 等于              
    ...:         print '__eq__'                      
    ...:         return self.area() == obj.area()
In [45]: r1 = Rectangle(5,6)                         
In [46]: r2 = Rectangle(3,9)                         
In [47]: r1 > r2   # 可以使用大于
__lt__                                               
__eq__                                               
Out[47]: True 
tips:使用 @total_ordering 修饰,可以根据给出的两个运算符进行推导。
方法二升级:定义一个基类支持多类型比较
In [48]: from abc import ABCMeta,abstractmethod           
    ...: @total_ordering                                  
    ...: class Shape(object):                             
    ...:     @abstractmethod      #子类必须实现的方法
    ...:     def area(self):                              
    ...:         pass                                     
    ...:     def __lt__(self,obj):                        
    ...:         print '__lt__'                           
    ...:         if not isinstance(obj,Shape):#判断类型是否有误
    ...:             raise TypeError('obj is not Shape!') 
    ...:         return self.area() < obj.area()          
    ...:     def __eq__(self,obj):                        
    ...:         print '__eq__'                           
    ...:         if not isinstance(obj,Shape):            
    ...:             raise TypeError('obj is not Shape!') 
    ...:         return self.area() == obj.area() 
In [49]: class Rectangle(Shape):                         
    ...:     def __init__(self,width,height):            
    ...:         self.width = width                      
    ...:         self.height = height                    
    ...:     def area(self):                             
    ...:         return self.width*self.height           
In [50]: class Circle(Shape):                            
    ...:     def __init__(self,r):                       
    ...:         self.r = r                              
    ...:     def area(self):                             
    ...:         return self.r**2*3.14                   
In [51]: r1 = Rectangle(9,5)                             
In [52]: c1 = Circle(4)
In [53]: print r1 > c1                                   
__lt__                                                   
False  
tips:通过定义基类,可以比较多种类的面积大小,就达到简化程序的目的。

8、如何在一个 for 语句中迭代多个可迭代对象?

方法一:zip 函数进行并行操作
例子:同时迭代4个列表
In [71]: data1 = [randint(60,100) for _ in xrange(10)]
In [72]: data2 = [randint(60,100) for _ in xrange(10)]
In [73]: data3 = [randint(60,100) for _ in xrange(10)]
In [75]: data4 = [randint(60,100) for _ in xrange(10)]
In [74]: for x,y,z,r in zip(data1,data2,data3,data4):# 解包
    ...:     total = x+y+z+r  
    ...:     print total
198
238
234
235
...
方法二:使用 chain 进行串行操作
例子:数据同上,统计大于80的项
In [78]: from itertools import chain
In [79]: count = 0 
In [81]: for s in chain(data1,data2,data3,data4):
    ...:     if s>80:
    ...:         count += 1
    ...:
In [82]: count
Out[82]: 17

你可能感兴趣的:(Python 进阶(下))