Python过滤序列元素的方法


Posted in Python onJuly 31, 2020

问题

你有一个数据序列,想利用一些规则从中提取出需要的值或者是缩短序列

解决方案

最简单的过滤序列元素的方法就是使用列表推导。比如:

>>> mylist = [1, 4, -5, 10, -7, 2, 3, -1]
>>> [n for n in mylist if n > 0]
[1, 4, 10, 2, 3]
>>> [n for n in mylist if n < 0]
[-5, -7, -1]
>>>

使用列表推导的一个潜在缺陷就是如果输入非常大的时候会产生一个非常大的结果集,占用大量内存。 如果你对内存比较敏感,那么你可以使用生成器表达式迭代产生过滤的元素。比如:

>>> pos = (n for n in mylist if n > 0)
>>> pos
<generator object <genexpr> at 0x1006a0eb0>
>>> for x in pos:
... print(x)
...
1
4
10
2
3
>>>

有时候,过滤规则比较复杂,不能简单的在列表推导或者生成器表达式中表达出来。 比如,假设过滤的时候需要处理一些异常或者其他复杂情况。这时候你可以将过滤代码放到一个函数中, 然后使用内建的 filter() 函数。示例如下:

values = ['1', '2', '-3', '-', '4', 'N/A', '5']
def is_int(val):
  try:
    x = int(val)
    return True
  except ValueError:
    return False
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]
>>> import math
>>> [math.sqrt(n) for n in mylist if n > 0]
[1.0, 2.0, 3.1622776601683795, 1.4142135623730951, 1.7320508075688772]
>>>

过滤操作的一个变种就是将不符合条件的值用新的值代替,而不是丢弃它们。 比如,在一列数据中你可能不仅想找到正数,而且还想将不是正数的数替换成指定的数。 通过将过滤条件放到条件表达式中去,可以很容易的解决这个问题,就像这样:

>>> clip_neg = [n if n > 0 else 0 for n in mylist]
>>> clip_neg
[1, 4, 0, 10, 0, 2, 3, 0]
>>> clip_pos = [n if n < 0 else 0 for n in mylist]
>>> clip_pos
[0, 0, -5, 0, -7, 0, 0, -1]
>>>

另外一个值得关注的过滤工具就是 itertools.compress() , 它以一个 iterable 对象和一个相对应的 Boolean 选择器序列作为输入参数。 然后输出 iterable 对象中对应选择器为 True 的元素。 当你需要用另外一个相关联的序列来过滤某个序列的时候,这个函数是非常有用的。 比如,假如现在你有下面两列数据:

addresses = [
  '5412 N CLARK',
  '5148 N CLARK',
  '5800 E 58TH',
  '2122 N CLARK',
  '5645 N RAVENSWOOD',
  '1060 W ADDISON',
  '4801 N BROADWAY',
  '1039 W GRANVILLE',
]
counts = [ 0, 3, 10, 4, 1, 7, 6, 1]

现在你想将那些对应 count 值大于5的地址全部输出,那么你可以这样做:

>>> from itertools import compress
>>> more5 = [n > 5 for n in counts]
>>> more5
[False, False, True, False, False, True, True, False]
>>> list(compress(addresses, more5))
['5800 E 58TH', '1060 W ADDISON', '4801 N BROADWAY']
>>>

这里的关键点在于先创建一个 Boolean 序列,指示哪些元素符合条件。 然后 compress() 函数根据这个序列去选择输出对应位置为 True 的元素。

filter() 函数类似, compress() 也是返回的一个迭代器。因此,如果你需要得到一个列表, 那么你需要使用 list() 来将结果转换为列表类型。

以上就是Python过滤序列元素的方法的详细内容,更多关于Python过滤序列元素的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python多线程编程(四):使用Lock互斥锁
Apr 05 Python
Python面向对象编程之继承与多态详解
Jan 16 Python
Python网络爬虫神器PyQuery的基本使用教程
Feb 03 Python
python3安装pip3(install pip3 for python 3.x)
Apr 03 Python
Python实现通过继承覆盖方法示例
Jul 02 Python
python实现的自动发送消息功能详解
Aug 15 Python
Python动态声明变量赋值代码实例
Dec 30 Python
Pycharm激活方法及详细教程(详细且实用)
May 12 Python
解决pyinstaller 打包exe文件太大,用pipenv 缩小exe的问题
Jul 13 Python
Python实现区域填充的示例代码
Feb 03 Python
教你如何使用Python实现二叉树结构及三种遍历
Jun 18 Python
Python使用BeautifulSoup4修改网页内容
May 20 Python
python中的django是做什么的
Jul 31 #Python
如何基于python把文字图片写入word文档
Jul 31 #Python
django教程如何自学
Jul 31 #Python
Python实现一个优先级队列的方法
Jul 31 #Python
django表单中的按钮获取数据的实例分析
Jul 31 #Python
pycharm中使用request和Pytest进行接口测试的方法
Jul 31 #Python
django创建css文件夹的具体方法
Jul 31 #Python
You might like
php计算几分钟前、几小时前、几天前的几个函数、类分享
2014/04/09 PHP
如何使用jQuery+PHP+MySQL来实现一个在线测试项目
2015/04/26 PHP
开启PHP的伪静态模式
2015/12/31 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
一个高效的JavaScript压缩工具下载集合
2007/03/06 Javascript
js对象之JS入门之Array对象操作小结
2011/01/09 Javascript
详解Javacript和AngularJS中的Promises
2016/02/09 Javascript
JS验证逗号隔开可以是中文字母数字
2016/04/22 Javascript
js遍历json的key和value的实例
2017/01/22 Javascript
JS简单判断函数是否存在的方法
2017/02/13 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
EasyUI创建人员树的实例代码
2017/09/15 Javascript
JavaScript中EventLoop介绍
2018/01/22 Javascript
解决vue+webpack项目接口跨域出现的问题
2020/08/10 Javascript
[05:00]TI9战队采访 - Royal Never Give Up
2019/08/20 DOTA
[08:06]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant 选手采访
2021/03/11 DOTA
Python中属性和描述符的正确使用
2016/08/23 Python
运动检测ViBe算法python实现代码
2018/01/09 Python
解析Python的缩进规则的使用
2019/01/16 Python
Python读取xlsx文件的实现方法
2019/07/04 Python
python3连接MySQL8.0的两种方式
2020/02/17 Python
Python函数参数分类原理详解
2020/05/28 Python
CSS3实现苹果手机解锁的字体闪亮效果示例
2021/01/05 HTML / CSS
idealfit英国:世界领先的女性健身用品和运动衣物品牌
2017/11/25 全球购物
linux面试题参考答案(5)
2016/11/05 面试题
物业管理毕业生个人的求职信
2013/11/30 职场文书
美术教学感言
2014/02/22 职场文书
2014两会学习心得:时代的发展
2014/03/17 职场文书
信电学院毕业生自荐书
2014/05/24 职场文书
五四演讲稿范文
2014/09/03 职场文书
在校大学生自我评价范文
2014/09/12 职场文书
小班教师个人总结
2015/02/05 职场文书
辩论赛开场白大全(主持人+辩手)
2015/05/29 职场文书
二十年同学聚会感言
2015/07/30 职场文书
曾国藩励志经典名言37句,蕴含哲理
2019/10/14 职场文书
sentinel支持的redis高可用集群配置详解
2022/04/01 Redis