Reputation: 93
I was trying to solve the following problem: Draw a star pattern that increases in every step (1st step: 1 star, 2nd step: 2 stars). E.g.
*
**
I am not sure why my code is not showing any output when I am writing return
? When I am writing print
, it is giving me the star output but also giving me None
. May I know why return
or print
are not working properly? I am using Python 3.7. My code is:
def string(inp):
for i in range (inp):
return i*"*"
print (string(5))
Upvotes: 2
Views: 7490
Reputation: 114518
A a re-entrant function that preserves state between calls is a generator. To make a generator function, change the keyword return
to yield
:
def string(n):
for i in range(n):
yield (i + 1) * '*'
Calling this version of string
will return a generator that yields a new line of your desired output at each iteration.
To print:
for line in string(5):
print(line)
To print all at once:
print('\n'.join(string(5)))
Upvotes: -1
Reputation: 61643
I will translate the code to plain English, as explicitly as I can:
Here are the rules that take a value `inp` and compute the `string` of that `inp`:
Letting `i` take on each integer value from 0 up to but not including `inp`:
We are done. The `string` of `inp` is equal to the string '*' repeated `i` times.
Compute the `string` of `5` and display it.
Hopefully the problem is evident: we can only be done with a task once, and i
is equal to 0 at that point, so our computed value is an empty string.
When I am writing
None
From the described behaviour, I assume that you mean that you tried to replace the word return
in your code with print
, giving:
def string(inp):
for i in range (inp):
print(i*"*")
print (string(5))
That produces the triangle, of course, except that
i
will be equal to 0 the first time through the loop, a blank line is printed; and since i
will be equal to 4 the last time through the loop, there is no *****
line.None
is printed, as you describe. This happens because the value computed by string
is the special value None
, which is then print
ed because you asked for it to be printed (print(string(5))
).In Python, each call to a function will return a value when it returns, whether or not you use return
and whether or not you specify a value to return
. The default is this special None
value, which is a unique object of its own type. It displays with the text None
when printed, but is different from a string with that text (in the same way that the integer 5
is different from the string "5"
).
May I know why
return
or
They are working exactly as designed. return
specifies the result of calling the function, and can only happen once per function, and does not cause anything to be displayed. print
displays what it is given.
If you wish to return
multiple values from a call, then you need to work around that restriction - either by using a generator instead (as in @MadPhysicist's or @wjandrea's answers), or by using some single, structured datum that contains all those values (for example, a list, or a tuple).
Upvotes: 1
Reputation: 33159
range
starts at 0
, and return
terminates a function, so that means string
will always return an empty string.
Here's one possible option for getting your expected result:
def stars(n):
for i in range(1, n+1): # Add one to start and stop
print(i * "*") # Print inside the function
stars(2) # Don't print outside the function
Output:
*
**
If you need to print outside the function, you could use a generator:
def stars(n):
for i in range(1, n+1):
yield i * "*" # "yield" is like "return" but can be used more than once
for s in stars(2):
print(s) # Print each string that gets yielded
# Or print all at once, using the "splat" unpacking operator
print(*stars(5), sep='\n')
Upvotes: 2
Reputation: 23
Using return won't print an output, use something like this:
def string(inp):
for i in range (inp):
print(i*"*")
string(5)
also this will only print 4, if you make it
for i in range(inp + 1):
It will work as intended, hope this helps!
Upvotes: 1