在先前的文章中,我们介绍了Linux中的管道工具,也学习了Scikit-Learn中的Pipeline。今天再来说一下如何在Python中使用管道操作,使得带来逻辑更加简单易懂。
案例展示
任务:给定一个整数数组,编写一个程序将3与所有奇数整数相乘。
解决方案很简单:
arr = [2, 3, 4, 5, 6, 7] output = [] for i in arr: if i % 2 != 0: output.append(i * 3) print(output)
一个更好的方式是使用Python自带的函数式编程方法map和filter。具体代码为:
arr = [2, 3, 4, 5, 6, 7] output = list(map(lambda x: x * 3, filter(lambda x: x % 2 != 0, arr))) print(output)
代码虽然简单,但是看起来还是有些混来,再来看看如何使用Pipe工具实现以上需求:
from pipe import select, where arr = [2, 3, 4, 5, 6, 7] output = list(arr | where(lambda x: x % 2 != 0) | select(lambda x: x * 3)) print(output)
是不是逻辑更加清晰了?
Python Pipe库简介
Pipe是一个Python库,可让你在Python中使用管道。管道(|)将一种方法的结果传递给另一种方法。Pipe将多个方法应用于Python可迭代对象时看起来更简洁。由于Pipe只提供了几个方法,所以学习Pipe也很容易。要安装Pipe,请输入:pip install pipewhere:可迭代对象中的过滤元素
与SQL类似,Pipe的where方法也可用于过滤可迭代对象中的元素。
select:将函数应用于可迭代对象
select方法类似于map方法。select将方法应用于可迭代的每个元素。
现在,你可能想知道:如果map和filter具有相同的功能,为什么我们需要where和select方法?这是因为你可以使用管道在另一个方法之后插入一个方法。因此,使用管道消除了嵌套的括号并使代码更具可读性。
from pipe import select, where arr = [2, 3, 4, 5, 6, 7] output = list(arr | where(lambda x: x % 2 != 0) | select(lambda x: x * 3) ) print(output)
chain方法:使用chain来链接一系列可迭代对象
from pipe import chain arr = [[1, 2, [3]], [4, 5]] output = list(arr | chain) print(output) #[1, 2, [3], 4, 5]
尽管应用chain可以使可迭代对象的嵌套较少,我们仍然需要一个更强大的工具。为了处理深度嵌套的列表,我们可以使用traverse代替。
traverse:递归展开可迭代对象
traverse方法可用于递归展开可迭代对象。你可以使用此方法将深度嵌套的列表转换为平面列表。
from pipe import traverse arr = [[1, 2, [3]], [4, 5]] output = list(arr | traverse) print(output) #[1, 2, 3, 4, 5]
让我们将此方法与select方法集成以获取字典的值并展平列表。
from pipe import traverse, select fruits = [ {"name": "apple", "price": [2, 5]}, {"name": "orange", "price": 4}, {"name": "grape", "price": 5} ] output = list(fruits | select(lambda fruit: fruit["price"]) | traverse) print(output) #[2, 5, 4, 5]
groupby:将列表中的元素分组
有时,使用特定函数对列表中的元素进行分组可能很有用。这可以通过groupby方法轻松完成。
为了看看这个方法是如何工作的,让我们把一个数字列表变成一个字典,这个字典根据数字是偶数还是奇数来分组。
from pipe import groupby, select items = range(10) output = list(items | groupby(lambda x: "Odd" if x % 2 else "Even") | select( lambda x: "{}: {}".format(x[0], list(x[1])))) print(output) #['Even: [0, 2, 4, 6, 8]', 'Odd: [1, 3, 5, 7, 9]']
dedup方法删除列表中的重复
这听起来可能并不有趣,因为set方法可以做同样的事情。
from pipe import dedup output = list([-1, 0, 0, 0, 1, 2, 3] | dedup)) print(output) #[-1, 0, 1, 2, 3]
但是,此方法更灵活,可以让你获取唯一元素。例如,你可以使用此方法获取一个小于5的唯一元素和另一个大于或等于5的唯一元素。
from pipe import dedup arr = [1, 2, 2, 3, 4, 5, 6, 6, 7, 9, 3, 3, 1] output = list(arr | dedup(lambda x: x < 5)) print(output) #[1, 5]
更多内容请查看官方文档。
参考链接: