2
\$\begingroup\$

Here I have some simple code that worries me, look at the second to last line of code, I have to return spam in order to change spam in the global space. Also is it bad to be writing code in this space and I should create a function or class to call from that space which contains most my code?

I found out very recently that I never even understood the differences between Python's identifiers compared to C or C++'s variables. This helps put into perspective why I always have so many errors in Python.

I do not want to continue writing code and get into a bad habit and this is why I want your opinion.

I also have a tendency to do things like spam = fun() because I do not know how to correctly make Python call a function which changes a variable in the scope of where the function was called. Instead I simply return things from the functions never learning how to correctly write code, I want to change that as soon as possible.

import random
MAX = 20

def randomize_list(the_list, x=MAX):
    for i in range(len(the_list)):
        the_list[i] = random.randint(1, x)

def lengthen_list(the_list, desired_length, x=MAX):
    if len(the_list) >= desired_length:
        print "erroneous call to lengthen_list(), desired_length is too small"
        return the_list
    while(len(the_list) < desired_length):
        the_list.append(random.randint(1, x))
        # organize the_set
        the_list = set(the_list)
        the_list = list(the_list)
    return the_list

spam = list(range(10))
randomize_list(spam, MAX)

print "the original list:"
print spam, '\n'

spam = set(spam)
spam = list(spam)

print "the set spam:"
print spam

print "the set spam with length 10"
spam = lengthen_list(spam, 10, MAX)
print spam

Please help me adopt a style which correctly fixes, in particular, the second to last line of code so that I do not need the function to do return things in order to work, if this is even possible.

\$\endgroup\$
4
  • \$\begingroup\$ Well, I am not a python expert and this is more like my general convention than python convention. You should not reuse variable name. For example, set(spam) and list(spam) should not be assign to the same variable. \$\endgroup\$
    – Tg.
    Commented Feb 21, 2013 at 5:07
  • \$\begingroup\$ @Tg. Yes I know what you mean. The point of the code I think you are talking about changes spam to a set and then back to a list. This is a quick and dirty way of removing repetitious values in the list and organizing them least to greatest in value. \$\endgroup\$
    – Leonardo
    Commented Feb 21, 2013 at 5:14
  • 1
    \$\begingroup\$ Well, others already comment on most of your concern. For about your quick and dirty way, here is the better version. uniqSpam = list(set(spam)) You should avoid any one-time-use intermediate variable if it does not cluttering much on the right hand side. \$\endgroup\$
    – Tg.
    Commented Feb 21, 2013 at 5:28
  • \$\begingroup\$ Since you wrote this question, our standards have been updated. Could you read How to Ask and update your question to match what it is now? \$\endgroup\$
    – anon
    Commented Apr 24, 2017 at 14:06

1 Answer 1

4
\$\begingroup\$

I also have a tendency to do things like spam = fun() because I do not know how to correctly make Python call a function which changes a variable in the scope of where the function was called.

You can't. You cannot replace a variable in an outer scope. So in your case, you cannot replace the list with a new list, although you can modify the list. To make it clear

variable = expression

replaces a variable, whereas pretty much anything else:

variable[:] = expression
variable.append(expression)
del variable[:]

Modifies the object. The bottom three will take effect across all references to the object. Whereas the one before replaces the object with another one and won't affect any other references.

Stylistically, it somestimes makes sense to have a function modify a list, and other times it makes sense for a function to return a whole new list. What makes sense depends on the situation. The one rule I'd pretty much always try to follow is to not do both.

def randomize_list(the_list, x=MAX):
    for i in range(len(the_list)):
        the_list[i] = random.randint(1, x)

This isn't a good place to use a modified list. The incoming list is ignored except for the length. It'd be more useful as a function that returns a a new list given a size something like:

def random_list(length, maximum = MAX):
    random_list = []
    for _ in range(length):
        random_list.append( random.randint(1, maximum) )
    return random_list

def lengthen_list(the_list, desired_length, x=MAX):
    if len(the_list) >= desired_length:
        print "erroneous call to lengthen_list(), desired_length is too small"

Don't report errors by print, raise an exception

 raise Exception("erroneous call...")


        return the_list
    while(len(the_list) < desired_length):
        the_list.append(random.randint(1, x))
        # organize the_set
        the_list = set(the_list)
        the_list = list(the_list)

That's not an efficient way to do that. You constantly convert back between a list and set. Instead do something like

 new_value = random.randint(1, maximum)
 if new_value not in the_list:
      the_list.append(new_value)

That way you avoid the jumping back and forth, and it also modifies the original object rather then creating a new list.

    return the_list

This particular function could go either way in terms of modifying or returning the list. Its a judgement call which way to go.

Also is it bad to be writing code in this space and I should create a function or class to call from that space which contains most my code?

Yes, you should really put everything in a function and not at the main level for all but the most trivial scripts.

\$\endgroup\$
2
  • \$\begingroup\$ I have not seen code like yours such as: for _ in range(length):, does the underscore just mean that we are not going to use some value from the range, we are instead going to do something length times? \$\endgroup\$
    – Leonardo
    Commented Feb 21, 2013 at 5:21
  • \$\begingroup\$ @Leonardo: yes, it's conventional to use _ for a loop variable that's otherwise unused. See here or here. \$\endgroup\$ Commented Feb 21, 2013 at 11:03

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.