Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python fluent filter, map, etc

I love python. However, one thing that bugs me a bit is that I don't know how to format functional activities in a fluid manner like a can in javascript.

example (randomly created on the spot): Can you help me convert this to python in a fluent looking manner?

var even_set = [1,2,3,4,5]
.filter(function(x){return x%2 === 0;})
.map(function(x){
    console.log(x); // prints it for fun
    return x;
})
.reduce(function(num_set, val) {
    num_set[val] = true;
}, {});

I'd like to know if there are fluid options? Maybe a library.

In general, I've been using list comprehensions for most things but it's a real problem if I want to print

e.g., How can I print every even number between 1 - 5 in python 2.x using list comprehension (Python 3 print() as a function but Python 2 it doesn't). It's also a bit annoying that a list is constructed and returned. I'd rather just for loop.

like image 512
ThinkBonobo Avatar asked Aug 16 '16 20:08

ThinkBonobo


1 Answers

I am looking now at an answer that strikes closer to the heart of the question:

fluentpy https://pypi.org/project/fluentpy/ :

Here is the kind of method chaining for collections that a streams programmer (in scala, java, others) will appreciate:

import fluentpy as _
(
  _(range(1,50+1))
  .map(_.each * 4)
  .filter(_.each <= 170)
  .filter(lambda each: len(str(each))==2)
  .filter(lambda each: each % 20 == 0)
  .enumerate()
  .map(lambda each: 'Result[%d]=%s' %(each[0],each[1]))
  .join(',')
  .print()
)

And it works fine:

Result[0]=20,Result[1]=40,Result[2]=60,Result[3]=80

I am just now trying this out. It will be a very good day today if this were working as it is shown above.

Update: Look at this: maybe python can start to be more reasonable as one-line shell scripts:

python3 -m fluentpy "lib.sys.stdin.readlines().map(str.lower).map(print)"

Here is it in action on command line:

$echo -e "Hello World line1\nLine 2\Line 3\nGoodbye" 
         | python3 -m fluentpy "lib.sys.stdin.readlines().map(str.lower).map(print)"

hello world line1

line 2

line 3

goodbye

There is an extra newline that should be cleaned up - but the gist of it is useful (to me anyways).

Update Here's yet another library/option : one that I adapted from a gist and is available on pipy as infixpy:

from infixpy import *
a = (Seq(range(1,51))
     .map(lambda x: x * 4)
     .filter(lambda x: x <= 170)
     .filter(lambda x: len(str(x)) == 2)
     .filter( lambda x: x % 20 ==0)
     .enumerate()                                            Ï
     .map(lambda x: 'Result[%d]=%s' %(x[0],x[1]))
     .mkstring(' .. '))
print(a)
like image 63
WestCoastProjects Avatar answered Sep 23 '22 03:09

WestCoastProjects