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 = '123@mail.com'  # Student1支持动态绑定
In [24]: s1.__dict__
Out[24]:
{'age': '20',
 'email': '123@mail.com',
 'mid': '01',
 'name': 'kim',
 'sex': 'male'}
In [28]: s2.email = '123@mail.com'  # 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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容