[Tutor] Finding more efficient ways

Dave Angel davea at davea.name
Wed Jul 10 14:52:20 CEST 2013


On 07/09/2013 04:04 PM, HRK wrote:
> Hello,
> I'm pretty new to Python so while I can make some basic stuff work, it doesn't look particularly pretty. I wanted to find better ways to solve the following two problems (the current code works, but is clunky.) Any tips or help appreciated. Thanks!
>

In your subject line you say "efficient" but here you say "(less) 
clunky".  Which is it?

For the first assignment, it's almost as simple as it's going to get, 
though you could eliminate the if test by using the dict.get() method.

http://docs.python.org/2/library/stdtypes.html?highlight=dict.get#dict.get


> PROBLEM #1
>
> heights = {"Mount Everest": 8848, "Mount Cook": 3754, "K2": 8611,
> "Ben Nevis": 1344, "Hekla": 1488}
>
> def mountain_height(heights, mountain):
>      '''Return the height of the mountain.
>      If the mountain isn't in the dictionary, the
>      height returned should be -1.
>      The search should ignore any spaces before or after the name.
>      >>> mountain_height({'K2':8611, 'Hekla':1488}, "K2")
>      8611
>      >>> mountain_height({'K2':8611, 'Hekla':1488}, "Hekla  ")
>      1488
>      >>> mountain_height({'K2':8611, 'Hekla':1488}, "Port Hills")
>      -1
>      '''
>      if mountain.strip() in heights:
>          return heights[mountain.strip()]
>      else:
>          return -1
>
> print(mountain_height({'K2':8611, 'Hekla':1488}, "K2"))
> #8611
> print(mountain_height({'K2':8611, 'Hekla':1488}, "Hekla  "))
> #1488
> print(mountain_height({'K2':8611, 'Hekla':1488}, "Port Hills"))
> #-1
>
>
> PROBLEM #2
>
> def is_up_down(values):
>      '''Return True if values is an up-down-sequence, otherwise
>      return False.
>      A sequence [x[0], x[1], x[2], ..., x[n]] is an up-down-sequence
>      if there is an index k such that
>      x[0] <= x[1] <= x[2] <= ... <= x[k-1] <= x[k] and
>      x[k] >= x[k+1] >= x[k+2] >= ... >= x[n-1] >= x[n] hold.
>      That is, the first part of the sequence is increasing and the
>      second part is decreasing.
>      Either part may be empty, so any increasing sequence and any
>      decreasing sequence is an up-down-sequence.
>      '''
>      flip = 0
>      value = 0
>      for item in values:
>          if flip == 2:
>              if item > value:
>                  return False
>          elif flip == 1:
>              if item < value:
>                  flip += 1
>              value = item
>          elif flip == 0:

Usually the lst elif should be spelled "else".  Or you should add 
another else afterwards.  Or add an assert() to double-check your logic.

>              if item > value:
>                  flip += 1
>              value = item
>      return True
>
> print(is_up_down([2,5,5,7,9,9,8]))
> #True
> print(is_up_down([2,5,5,7,9,8,9]))
> #False
> print(is_up_down([9,8]))
> #True
> print(is_up_down([13]))
> #True


Here, your code may be about as fast as it's going to get.  But it's 
very hard to follow, which may be what you mean by 'clunky.'  If it were 
my problem, I'd make the code much slower by defining a second function 
that checks whether a sequence is monotonic, and if so which way.  Then 
the main function will simply loop through the sequence, checking the 
head and tail with the second function.  As soon as it reaches a point 
where the head and tail are both monotonic, and with the opposite 
direction, you're done.


-- 
DaveA



More information about the Tutor mailing list