Python过滤序列元素的方法
问题
你有一个数据序列,想利用一些规则从中提取出需要的值或者是缩短序列
解决方案
最简单的过滤序列元素的方法就是使用列表推导。比如:
>>>mylist=[1,4,-5,10,-7,2,3,-1] >>>[nforninmylistifn>0] [1,4,10,2,3] >>>[nforninmylistifn<0] [-5,-7,-1] >>>
使用列表推导的一个潜在缺陷就是如果输入非常大的时候会产生一个非常大的结果集,占用大量内存。如果你对内存比较敏感,那么你可以使用生成器表达式迭代产生过滤的元素。比如:
>>>pos=(nforninmylistifn>0) >>>posat0x1006a0eb0> >>>forxinpos: ...print(x) ... 1 4 10 2 3 >>>
有时候,过滤规则比较复杂,不能简单的在列表推导或者生成器表达式中表达出来。比如,假设过滤的时候需要处理一些异常或者其他复杂情况。这时候你可以将过滤代码放到一个函数中,然后使用内建的filter()函数。示例如下:
values=['1','2','-3','-','4','N/A','5'] defis_int(val): try: x=int(val) returnTrue exceptValueError: returnFalse ivals=list(filter(is_int,values)) print(ivals) #Outputs['1','2','-3','4','5']
filter()函数创建了一个迭代器,因此如果你想得到一个列表的话,就得像示例那样使用list()去转换。
讨论
列表推导和生成器表达式通常情况下是过滤数据最简单的方式。其实它们还能在过滤的时候转换数据。比如:
>>>mylist=[1,4,-5,10,-7,2,3,-1] >>>importmath >>>[math.sqrt(n)forninmylistifn>0] [1.0,2.0,3.1622776601683795,1.4142135623730951,1.7320508075688772] >>>
过滤操作的一个变种就是将不符合条件的值用新的值代替,而不是丢弃它们。比如,在一列数据中你可能不仅想找到正数,而且还想将不是正数的数替换成指定的数。通过将过滤条件放到条件表达式中去,可以很容易的解决这个问题,就像这样:
>>>clip_neg=[nifn>0else0forninmylist] >>>clip_neg [1,4,0,10,0,2,3,0] >>>clip_pos=[nifn<0else0forninmylist] >>>clip_pos [0,0,-5,0,-7,0,0,-1] >>>
另外一个值得关注的过滤工具就是itertools.compress(),它以一个iterable对象和一个相对应的Boolean选择器序列作为输入参数。然后输出iterable对象中对应选择器为True的元素。当你需要用另外一个相关联的序列来过滤某个序列的时候,这个函数是非常有用的。比如,假如现在你有下面两列数据:
addresses=[ '5412NCLARK', '5148NCLARK', '5800E58TH', '2122NCLARK', '5645NRAVENSWOOD', '1060WADDISON', '4801NBROADWAY', '1039WGRANVILLE', ] counts=[0,3,10,4,1,7,6,1]
现在你想将那些对应count值大于5的地址全部输出,那么你可以这样做:
>>>fromitertoolsimportcompress >>>more5=[n>5fornincounts] >>>more5 [False,False,True,False,False,True,True,False] >>>list(compress(addresses,more5)) ['5800E58TH','1060WADDISON','4801NBROADWAY'] >>>
这里的关键点在于先创建一个Boolean序列,指示哪些元素符合条件。然后compress()函数根据这个序列去选择输出对应位置为True的元素。
和filter()函数类似,compress()也是返回的一个迭代器。因此,如果你需要得到一个列表,那么你需要使用list()来将结果转换为列表类型。
以上就是Python过滤序列元素的方法的详细内容,更多关于Python过滤序列元素的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。