Brian van den Broek said unto the world upon 2005-03-27 14:12:
> Charles Hartman said unto the world upon 2005-03-27 13:35:> >> On Mar 27, 2005, at 1:18 PM, Brian van den Broek wrote:>>>>> >>> def some_arbitrary_function(y):>>> ... return ( (y * 42) - 19 ) % 12>>> ...>>> >>> [some_arbitrary_function(len(x)) for x in lines.split()]>>> [5, 5, 11, 11, 5, 11, 5, 11]>>> >>>>>>>>>>>> I could be missing some edge cases, but it seems to me that if you >>> have list comps you don't really need map, filter, and the like. The >>> map portion can be done by nested function applications in the list >>> comp itself.>>>>>>>> A good point, and I think I see that. But ultimately what I'm >> wondering is whether a construction like this [1]:>>>> for s in possScansions:>> for a in algorithms:>> (feet, test) = self.DoAlgorithm(a, s)>> complexities[(s, a)] = (self._measureComplexity(feet, >> test), len(feet))>>>> can be condensed in one or more of these ways. (Whether the result >> would be readable / maintainable is a separate question. So is whether >> it would be more efficient. At the moment I'm just trying to get clear >> about the syntax.)>>>> [1] possScansions is a list of strings; algorithms is a list of ints; >> feet is a list of strings; test is a list of Booleans. complexities is >> a dictionary whose keys are those two-item tuples and whose values are >> the integers returned by self._measureComplexity>>>> Charles Hartman> > > Hi Charles,> > Is the code below the sort of thing you had in mind?> > (I should be quite upset if I actually came across such code in the wild.)> > >>> # set-up with arbitrary functions, etc.> >>> string_list = ['a', 'list of', 'arbitrary', 'strings']> >>> int_list = [3, 5, 42]> >>> def some_function(a, s):> ... if len(a) > s:> ... chunk = a[s:]> ... else:> ... chunk = None> ... return len(a) > s, chunk> ...> >>> def another_function(x, y):> ... if y:> ... return x + len(y)> ... else:> ... return x> ...> >>> complexities = {}> >>> simpler = {}> >>> # The structure you have above -- modulo that I flipped> >>> # the order of arguments in the first function due to> >>> # inattention (it doesn't matter, though).> >>> for s in string_list:> ... for i in int_list:> ... (feet, test) = some_function(s, i)> ... simpler[(s, i)] = another_function(feet, test)> ...> >>> # The evil way:> >>> # (Please don't do this, at least IMHO)> >>> for t in [(s, i, another_function(*some_function(s, i))) for s in > string_list for i in int_list]:> ... complexities[(t[0], t[1])] = t[2]> ...> >>> simpler == complexities> True> >>>> > I've not the glimmer of a clue which would be faster, and don't care to > check -- the evil way could be 5 times faster, and I wouldn't want it in > my code :-)
Sorry for the self-reply, but I just saw how to crank the evil up a
notch, and get it as a one-liner to boot:
>>> complexities = {}>>> side_effect_list = [complexities.__setitem__((s, i),
another_function(*some_function(s, i))) for s in string_list for i in
int_list]
>>> simpler == complexities
True
>>> side_effect_list
[None, None, None, None, None, None, None, None, None, None, None, None]
>>>
Best,
Brian vdB