[Tutor] replacing a loop
johnf
johnf at jfcomputer.com
Mon Jun 24 18:24:51 EDT 2019
Thank you - it worked! I'm glad you are no longer sleepy!
Actually I wanted the naming to remain consistent with the other loops
So the name of the function/method (it is in a class) caused the use of
the underscore
locChoices == location choices
def locChoices(self) cause me to use loc_Choices in the code.
I am torn about the readability of the code - at least in my mind I can
read the loop a lot easier than I can read the comprehension.
Of course I considered the use of a function where I passed the required
parameters. But the issue is the access to the data - that getDataSet()
was a performance hit when I used a passed parameter. I could have
opened/accessed/retrieve the data during the opening but thought it best
to use a lazy data access as needed.
Today was not really about performance but more about learning to use
the comprehension. You see I did attempt to do create the
comprehension. But after seeing your code I realized that I had the '['
and the '{' confused. I believed I had to use '{'. I just reviewed a
tutorial off the net and that was what they were using.
Thanks again,
Johnf
>
> Just because this morning I needed something to kick-start my sleepy
> brain into being able to "think"...
>
>
> When most people think of 'multiples' in the context of
> list-comprehensions, they are talking about "nested-loops" - which are
> easy-enough (or at least, well-documented).
>
> However, I've often wondered about the multiple being on the
> 'left-hand side' of the equation/expression, and whether that is even
> possible?
>
> It is!
> Thus:
>
> python3
> Python 3.6.8 (default, Mar 21 2019, 10:08:12)
> [GCC 8.3.1 20190223 (Red Hat 8.3.1-2)] on linux
> Type "help", "copyright", "credits" or "license" for more information.
>
> # build the data-structure (I hope)
> >>> d1 = { 'pkid':1, 'facility':'here' }
> >>> d2 = { 'pkid':2, 'facility':'there' }
> >>> d3 = { 'pkid':3, 'facility':'nowhere' }
> >>> locDS = ( d1, d2, d3 )
>
> # let's check that the data-format is as-described?
> >>> type( locDS )
> <class 'tuple'>
> >>> for row in locDS: print( row )
> ...
> {'pkid': 1, 'facility': 'here'}
> {'pkid': 2, 'facility': 'there'}
> {'pkid': 3, 'facility': 'nowhere'}
> # are we on the right track?
>
> # this is the original code and approach
> >>> loc_Choices = [ '<None>' ]
> >>> locKeys = [ 0 ]
> >>> for row in locDS:
> ... loc_Choices.append( row[ 'facility' ] )
> ... locKeys.append( row[ 'pkid' ] )
> ...
> # which (I hope) shows the existing (and desired) results
> >>> print( loc_Choices )
> ['<None>', 'here', 'there', 'nowhere']
> >>> print( locKeys )
> [0, 1, 2, 3]
>
> # we can do the list inits, cf leaving it to the list comprehension
> >>> loc_Choices = [ '<None>' ]
> >>> locKeys = [ 0 ]
>
> # but how might we achieve this using a (single) list comprehension?
> >>> [ [ loc_Choices.append( row[ 'facility' ] ), locKeys.append( row[
> 'pkid' ] ) ] for row in locDS ]
> # in (proper) code, I'd format this over two lines (at least)
>
> # correct me if I'm wrong, but these o/ps will
> # 'disappear into the ether' when run within a pgm...
> [[None, None], [None, None], [None, None]]
>
> # leaving us with 'the proof of the pudding'
> >>> print( loc_Choices )
> ['<None>', 'here', 'there', 'nowhere']
> >>> print( locKeys )
> [0, 1, 2, 3]
> >>>
>
>
> Possible considerations:
>
> 1 some sample data would have eased the way/its lack leaves room for
> misinterpretation
>
> 2 a list comprehension normally executes more quickly than the
> traditional (long-form) multi-line code-block. However, it would be
> worth measuring that on your particular machine h/w and Py__version__.
> The other 'efficiency' is readability, but "elegance" is largely a
> matter of (personal) taste. So that ('mine-field') I leave to you...
>
> 3 taking the multi-line code-block and splitting it into TWO separate
> (consecutive) list comprehensions (one for loc_Choices and the other
> for locKeys) will most-likely be noticeably MORE 'expensive'
>
> 4 it is no matter if row/the locDS tuple dict-elements contain more
> key-value pairs
>
> 5 during code review, my colleagues would delight in criticising the
> choice of names such as locKeys - describing them as "JavaScript" (a
> 'dirty word' to some), loc_Choices as contrary to PEP-8 ("flake", or
> whatever), etc - despite that I have a little 'set' of abbreviations
> with which I do the same, eg locNR. YMMV!
>
> 6 however, this simple boy will venture criticism of the inconsistency
> in using the underline word-separator, eg locKeys but loc_Choices.
> Even more potential for confusion: locChoices and loc_Choices!?
>
> 7 consider the data structures (outside of our view, here). Assuming
> there are more elements in each 'loc dict', might it be just as easy
> to leave the two pertinent elements 'there' and iterate over locDS
> when actually applied. Alternately, perhaps it might be better to
> construct a dictionary with the 'pkid's as keys and the 'facility' as
> values for direct-access application? Not knowing how the structure(s)
> will be utilised makes this pure speculation!
>
> 8 any?every time "similar loops" are found, re-factor to a function
> (let's see if that philosophy kicks-off a retort or two...)
>
> 9 was it Knuth who described "premature optimisation" as "evil"?
> Certainly I'm a believer in 'make it work before you make it better'.
> So, (after all that!) what are we really achieving here? With such
> quantities, is it critical to 'save time'? If so, is this part of the
> code really the greatest time-sink?
> (and we're back to the 'readability' consideration, previously mentioned)
>
>
> Thanks, for the provocation into answering this long-held question -
> and for the fact that my brain isn't sleepy any longer.
> (mind you, such exertion suggests it must be time for a tea-break)...
More information about the Tutor
mailing list