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.
-
\$\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.– Tg.2013年02月21日 05:07:22 +00:00Commented 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– Leonardo2013年02月21日 05:14:50 +00:00Commented 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.– Tg.2013年02月21日 05:28:26 +00:00Commented 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– anon2017年04月24日 14:06:50 +00:00Commented Apr 24, 2017 at 14:06
1 Answer 1
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.
-
\$\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 somethinglength
times? \$\endgroup\$Leonardo– Leonardo2013年02月21日 05:21:29 +00:00Commented 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\$Gareth Rees– Gareth Rees2013年02月21日 11:03:38 +00:00Commented Feb 21, 2013 at 11:03