Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript-like array-method chaining in Python?

Tags:

python

I'm coming into python from a javascript background. In JS we can do array-method chaining, and it's awesome (especially with arrow functions):

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

Is something like array-method chaining possible in python and, if not, then why on earth not?

like image 664
Anastasius Vivaldus Avatar asked Jan 01 '23 13:01

Anastasius Vivaldus


2 Answers

In Python, you'd do:

from operator import attrgetter
map(lambda x: x.name, 
    sorted(filter(lambda x: x.count > 10, someArray), 
           key=attrgetter("count"))

Syntax is slightly different, but it should basically do the same. Does this answer your question?

Edit

If you really want a more "chain-like" syntax, you can take a look at toolz. From their docs:

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

Edit 2

Thanks to @mpium for suggesting PyFunctional, which seems to have an even cooler syntax for this:

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
like image 139
Felix Avatar answered Jan 04 '23 03:01

Felix


You can do method chaining but the builtin list type does not support the operations you are requesting as methods (e.g. map is a builtin). @Felix's excellent answer looks right to me in terms of doing the operations you gave in your example. If you want to chain methods, all that's required is that each method returns an object which implements the next method.

Simple example:

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"
        )
like image 32
Charles Landau Avatar answered Jan 04 '23 02:01

Charles Landau