On Saturday, October 1, 2016 at 7:02:58 PM UTC+5:30, Jussi Piitulainen wrote: > Rustom Mody writes: > > > And then define comprehensions not as now done in terms of for loops > > that mutatingly extend the list being built up but as recursive > > functions that get (re)called for every new value of the comprehension > > variable passed and therefore fresh-bound as parameter > > You'd get the magical semantics for comprehensions from the current > definition of comprehension semantics in terms of the loop, if the loop > semantics was magical. Let me demonstrate. (The b-word is unfortunately > not available, so I substitute "magical" instead.) > > # delayd = [ lambda : c for c in "abracadabra" ] > # is roughly/almost equal to the following. > > delayd = [] > for c in "abracadabra": > delayd.append(lambda : c) > > print('Python:', ''.join(f() for f in delayd)) > > # But that for-loop could have been roughly equal to the following, > # giving both the comprehension and the underlying for-loop a > # semantics that some people say they would prefer. > > delayd = [] # reset the list, not part of the loop > > g1 = iter("abracadabra") > try: > while True: > def g2(c): > delayd.append(lambda : c) > g2(next(g1)) > except StopIteration: > pass > > print('Magick:', ''.join(f() for f in delayd)) > > # Output from the above: > # Python: aaaaaaaaaaa > # Magick: abracadabra
Hoo boy1 Thats some tour de force and makes my head spin Point can be made more simply with map ie if we *define* [exp for cv in l] as map(lambda cv: exp, l) the problem vanishes Demo: First a helper function for demoing: def pam(fl,x): return map(lambda f: f(x), fl) # pam is the complement to map; map runs one fnc on a list of args # pam runs a list of funcs on one arg Trying to make a list of functions that add one, two and three to their arguments fl = [lambda x: x + cv for cv in [1,2,3]] Broken because of python's wrong LC semantics: >>> pam(fl, 3) [6, 6, 6] Transform the LC into a map with the rule above: fl_good = map((lambda cv :lambda x: x+cv), [1,2,3]) Works! >>> pam(fl_good, 3) [4, 5, 6] >>> Which is not very far from the standard workaround for this gotcha: >>> fl_workaround = [lambda x, cv=cv: x+cv for cv in [1,2,3]] >>> pam(fl_workaround, 3) [4, 5, 6] >>> Maybe we could say the workaround is the map definition uncurried And then re-comprehension-ified -- https://mail.python.org/mailman/listinfo/python-list