Python Forum
wishing for a 3-way loop construct
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
wishing for a 3-way loop construct
#11
i really don't know how common it is. perhaps around 3% of code i have written could have used it.  i've had this in mind for many years since back in the days i did stuff in c.  there are many languages and a few do have obscure stuff.  i've also seen modified languages have some interesting added stuff, such as watfor-77 (way back before i did c).

i enjoyed playing with new languages a lot.  although i did not feel this way at the time, an interesting language i ran across was clu.  i remember something like generators in it.  if it had had duck-typing i might have fallen in love with it back then.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#12
I'd still like to see an example, but I felt inspired to show how this might be done in Scala
def handler[T](list: List[T])(f: T => Unit)(g: T => Unit)(h: T => Unit) = {
    f(list.head)
    list.tail.init.map(g)
    h(list.last)
}

handler(List(1, 2, 3, 4, 5))(first => println(first)) { x =>
    println(x * x)
} (last => println(last))
Output:
1 4 9 16 5
The main thing that makes this halfway decent is proper lambdas. The multiple parameter list syntax is nice for the definition, but Python could use nested functions for the definitions.

In Scala, parenthesis and braces are largely interchangeable, so this (lazily named) handler can easily have bigger / smaller parts.

Added in edit: this is just an example, not optimized for performance, cases where the list length is less than tree, or anything else than a super lean example.
Reply
#13
i am rewriting my pipeline code to: (1) clean it up, and (2) make it into a class (to be able to instantiate it more than once).  the interesting part is the loop which goes through each command, setting up the pipes between processes.  for N commands there will be N-1 pipes and both the first and last have different file descriptor set up (the first will have stdin and the last will have stdout).  i want to delay pipe creation until the processes are created so they can be closed out of the parent as soon as possible to minimize file descriptor numbering impacts.  so the loop will go through the indexes of all commands/processes and do first and last (detected by the index) differently.  two special cases: one command and zero commands.  zero is easy enough to handle.  i'm trying to make the first/last logic handle the one command case whenever it gets it.  the zero case should simply be the loop not executing the loop body at all.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#14
I'm a little late with this reply, but enumerate() might be a good way to do it.  Can't post a clickable link, but it's one of the built-in functions and returns an iterable of tuples like (index, item).

words = "the quick brown fox jumped over the lazy dog".split()

def isFirstIndex(index, lst):
    return index == 0 

def isLastIndex(index, lst):
    return index == len(lst) - 1 

for i, word in enumerate(words):
   if isFirstIndex(i, words):
       print(word.upper(), end=' ')

   elif isLastIndex(i, words):
       print(word[::-1] + '.')

   else:
       print(word, end=' ')
Output:
THE quick brown fox jumped over the lazy god.
Reply
#15
the way i figure i would deal with my pipeline issue is make a list of lists with the first 2 elements being False and False and the remaining element(s) describing the command.  then i would do list[0][[0],list[-1][1]=True,True.  then when i loop through the list to set up command processes and pipes like for this in cmdlist: i would have if this[0]: for one case and if this[1]: for the other.  this is simple enough, i think.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#16
def joingenerator(l):
    yield false,l[0]
    for x in l[1:]:
        yield true,x

for dojoin,x in joingenerator(somelist):
    if dojoin:
        print " and "
    print x
 
Unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
Your one-stop place for all your GIMP needs: gimp-forum.net
Reply
#17
Another way would be to use zip() on two copies of the list, but shifted.  This would give you tuples of (source process, destination process), except the first one would have a source of None, and the last would have a destination of None.

# [None, P1, P2, P3]
sources = [None] + processes

# [P1, P2, P3, None]
destinations = processes + [None]

for source, dest in zip(sources, destinations):
   if source is None:
       dest.input = sys.stdin
   elif dest is None:
       source.output = sys.stdout
   else:
       source.output = dest.input = Pipe()
 

Except you probably want to use some other word than input, since that's another built-in function.  Dodgy
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020