Python中类似于JavaScript数组方法链的实现方式?

4

我从JavaScript背景进入Python。在JS中,我们可以进行数组方法链式调用,这是很棒的(特别是使用箭头函数):

someArray
.filter(x => x.count > 10)
.sort((a, b) => a.count - b.count)
.map(x => x.name)

在 Python 中是否可以像数组方法链一样进行操作,如果不行,那么为什么会这样?

4个回答

7
在Python中,您可以这样做:
from operator import attrgetter
map(lambda x: x.name, 
    sorted(filter(lambda x: x.count > 10, someArray), 
           key=attrgetter("count"))

语法略有不同,但基本上应该做相同的事情。这个回答解决了你的问题吗?

编辑

如果你真的想要更多"链式"语法,你可以看一下toolz。从他们的文档中得知:

>>> from toolz.curried import pipe, map, filter, get
>>> pipe(accounts, filter(lambda acc: acc[2] > 150),
...                map(get([1, 2])),
...                list)

编辑 2

感谢 @mpium 提供的建议,推荐使用 PyFunctional,其语法似乎更加酷炫:

from functional import seq

seq(1, 2, 3, 4)\
    .map(lambda x: x * 2)\
    .filter(lambda x: x > 4)\
    .reduce(lambda x, y: x + y)
# 14

sorted 函数中不是缺少了一个 key 参数吗? - hiro protagonist
@hiroprotagonist 你说得对,现在应该已经修复了。谢谢! - Felix
3
您可以查看 PyFunctional,它类似于 toolz。 - mpium
好的建议,我不知道PyFunctional。我编辑了我的答案,谢谢;-) - Felix

1
在Python中,你可以像这样构建一个数据管道(这与方法链截然相反):
a1 = (item for item in someArray if item.count > 10)
a2 = sorted(a1, key=lambda x: x.count)
a3 = [item.name for item in a2]

请注意a1是一个生成器表达式(不是list),它不存储元素而是即时生成它们。
当然,你可以将它串联在一起(但这样做可读性较差)。
[item.name for item in sorted(
 (item for item in someArray if item.count > 10), key=lambda x: x.count)]

请注意,在Python中,更改实例的方法(例如list.sort())通常会返回None。因此,简单的方法链接对于list不起作用。
如果您使用返回self的库进行操作,方法链接将起作用。

1
你可以使用方法链,但内置的list类型不支持你请求的操作作为方法(例如map是内置的)。@Felix的优秀答案在执行你提供的操作时看起来正确。如果你想链接方法,只需要每个方法返回实现下一个方法的对象即可。
简单的例子:
list("234").copy( # Copy once
  ).copy( # Twice
    ).append("Dog" # Returns None, so we can't continue chaining
      ).copy( # AttributeError because None has no method "copy"
        )

0

是的,它有效。

方法链在多种编程语言中都适用。通常情况下,你会从该方法中返回 this、self 或者当前对象。

class Foo(object):
    def bar(self):
        print "Foo.bar called"
        return self
    def baz(self):
        print "Foo.baz called"
        return self

foo = Foo()
foo2 = foo.bar().baz()

许多Python内置的列表方法是就地修改列表的,因此在其上进行链式操作是很困难的。但是,如果需要某些功能,可以创建包装器类来封装这些方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接