Left to right application of operations on a list in Python 3

functional-programming, list, operator-precedence, python

Solution

The answer from @JohanL does a nice job of seeing what the closest equivalent is in standard python libraries.

I ended up adapting a gist from Matt Hagy in November 2019 that is now in `pypi`

https://pypi.org/project/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)

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

Other approaches described in other answers

pyxtension https://stackoverflow.com/a/62585964/1056563

from pyxtension.streams import stream

sspipe https://stackoverflow.com/a/56492324/1056563

from sspipe import p, px

Older approaches

I found a more appealing toolkit in Fall 2018

https://github.com/dwt/fluent

After a fairly thorough review of the available third party libraries it seems the `Pipe` https://github.com/JulienPalard/Pipe best suits the needs .

You can create your own pipeline functions. I put it to work for wrangling some text shown below. the bolded line is where the work happens. All those `@Pipe` stuff I only have to code once and then can re-use.

The task here is to associate the abbreviation in the first text:

rawLabels="""Country: Name of country
Agr: Percentage employed in agriculture
Min: Percentage employed in mining
Man: Percentage employed in manufacturing
PS: Percentage employed in power supply industries
Con: Percentage employed in construction
SI: Percentage employed in service industries
Fin: Percentage employed in finance
SPS: Percentage employed in social and personal services
TC: Percentage employed in transport and communications"""

With an associated tag in this second text:

mylabs = "Country Agriculture Mining Manufacturing Power Construction Service Finance Social Transport"

Here's the one-time coding for the functional operations (reuse in subsequent pipelines):

@Pipe
def split(iterable, delim= ' '):
    for s in iterable: yield s.split(delim)

@Pipe
def trim(iterable):
    for s in iterable: yield s.strip()

@Pipe
def pzip(iterable,coll):
    for s in zip(list(iterable),coll): yield s

@Pipe
def slice(iterable, dim):
  if len(dim)==1:
    for x in iterable:
      yield x[dim[0]]
  elif len(dim)==2:
    for x in iterable:
      for y in x[dim[0]]:
        yield y[dim[1]]
    
@Pipe
def toMap(iterable):
  return dict(list(iterable))

And here's the big finale : all in one pipeline:

labels = (rawLabels.split('\n') 
     | trim 
     | split(':')
     | slice([0])
     | pzip(mylabs.split(' '))
     | toMap )

And the result:

print('labels=%s' % repr(labels))

labels={'PS': 'Power', 'Min': 'Mining', 'Country': 'Country', 'SPS': 'Social', 'TC': 'Transport', 'SI': 'Service', 'Con': 'Construction', 'Fin': 'Finance', 'Agr': 'Agriculture', 'Man': 'Manufacturing'}

Problem

Is there any possible way to achieve a non-lazy left to right invocation of operations on a list in Python? E.g. Scala: ``` val a = ((1 to 50) .map(_ * 4) .filter( _ <= 170) .filter(_.toString.length == 2) .filter (_ % 20 == 0) .zipWithIndex .map{ case(x,n) => s"Result[$n]=$x"} .mkString(" .. ")) a: String = Result[0]=20 .. Result[1]=40 .. Result[2]=60 .. Result[3]=80 ``` While I realize many folks will not prefer the above syntax, I like the ability to move left to right and add arbitrary operations as we go. The Python `for` comprehension is IMO not easy to read when there are three or more operations. The result seems to be we're required to break everything up into chunks. ``` [f(a) for a in g(b) for b in h(c) for ..] ``` Is there any chance for the approach mentioned? Note: I tried out a few libraries including `toolz.functoolz`. That one is complicated by Python 3 lazy evaluation: each level returns a `map` object. In addition, it is not apparent that it can operate on an input `list`.

Original source

Related problems