list-comprehension and map question (simple)
Brian van den Broek
bvande at po-box.mcgill.ca
Sun Mar 27 14:12:46 EST 2005
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 :-)
Best,
Brian vdB
More information about the Python-list
mailing list