I had some difficulty to find the trick:
def diamond(ni):
li = [ i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
li.extend(i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in range(2,ni+1))
return '\n'.join(li)
print diamond(7)
draws
*************
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
*************
Noticing that
li.extend(i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in range(2,ni+1))
does the same (less one line) than
li = [ i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
but in reverse order, we can simplify:
def symetric_diamond(ni):
li = [i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
li.extend(li[-2::-1])
return '\n'.join(li)
Please, note that
print '\n'.join(str(i) for i in xrange(500))
is displayed instantly, because the program computes the string '\n'.join(str(i) for i in xrange(500)) before to print it in one shot, while
for i in xrange(500):
print str(i)
is far longer to be displayed, because the computer prints 500 strings one after the other, and each call to print is long
.
There's another manner to print a diamond,I will write it now.
Plus
def format_diamond(nl):
ni = (nl+1)/2
li = ['{:{fill}{align}{width}}'.format((2*(ni-x) - 1)*' ',fill='*',align='^',width=2*ni-1)
for x in xrange(ni,0,-1)]
li.extend(li[-2::-1])
return '\n'.join(li)
-> all these functions give a diamond of nl-1 lines when nl is even.
Edit
Finally, what I prefer is:
def symetric_diamond(nl):
'''Returns a diamond of nl lines if nl is odd,
and nl-1 lines if nl is even'''
ni = (nl+1)//2
li = [ (2*ni-1) * '*' ]
li.extend(i*'*' + (2*(ni-i) - 1)*' ' +i*'*' for i in xrange(ni-1,0,-1))
li += reversed(li[0:-1]) # in-place extension
return '\n'.join(li)
because of the in-place extensions (with extend and reversed) and the absence of the horrid (i - i//ni)*'*'