2
\$\begingroup\$

For practice I wrote a function to generate a list of numbers from a start to an end by a step. I couldn't make it- like the built-in range- default start to 0, because all optional parameters must come after required ones, so def range(start=0, end, step=1) won't work.

Here's my script:

def Range(start, end, step=1):
    """Returns a list of numbers beginning from start and
       incremented by step to end (with end excluded).

      start: an integer specifies the start of the range.

      end: an integer specifies the end of the range.

      step: an integer specifies the number to increment by.
      """

    num = start
    result = []

    while num < end:
        result.append(num)
        num += step

    return result

How can it be refactored and optimized ?

Notes:

  • I'm a hobbyist and beginner (in Python in particular, and programming in general).
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I'm not sure how the actual python implementation for this works but you could query the length of *args to assign the parameters to the right variables:

def Range(*args):
    len_args = len(args)
    if len_args == 2:
        args = args + (1,)
    elif len_args == 1:
        args = (0, args[0], 1)
    start, end, step = args
    ...

In addition I would make this a generator (similar to how it is in python 3.x):

def Range(*args):
    len_args = len(args)
    if len_args == 2:
        args = args + (1,)
    elif len_args == 1:
        args = (0, args[0], 1)
    start, end, step = args

    while start < end:
        yield start
        start += step
\$\endgroup\$
8
  • \$\begingroup\$ That is good! I've thought of using *args, but wasn't sure how to make that. Thank you! \$\endgroup\$ Commented Sep 27, 2016 at 16:09
  • \$\begingroup\$ But when doing that how can we make the function usage easy? The user won't know in what order he should put arguments. I think the docstring need to be edited. \$\endgroup\$ Commented Sep 27, 2016 at 16:14
  • 2
    \$\begingroup\$ You can try def Range(start, stop=None, step=1): if stop is None: start, stop = 0, start \$\endgroup\$ Commented Sep 27, 2016 at 16:16
  • \$\begingroup\$ I've some questions. Is using len_args = len(args) better than using len(args) in each boolean expression? Does that avoid re-computation and make the script faster? \$\endgroup\$ Commented Sep 27, 2016 at 17:12
  • \$\begingroup\$ @Mahmud In theory, yes. in practice len is implemented very efficiently and calling it twice will hardly be worth the overhead of saving it in a variable. \$\endgroup\$
    – Graipher
    Commented Sep 27, 2016 at 18:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.