正好19行的钻石Python
可能重复的问题:
ASCII Python Art # 2
i = 10
while i>0:
print i*'*' + 2*(10-i)*' ' + i*'*'
i -=1
for x in range(1,11):
print x* '*' + 2*(10-x)*' '+ x*'*'
x +=1
我想用星号(*)画一个19行的菱形。结果我得到了20行。
我想要的效果是:
********************
********* *********
******** ********
******* *******
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********************
我该怎么才能去掉星号中间部分的高度重复呢?
谢谢!
5 个回答
2
我在找这个技巧的时候遇到了一些困难:
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)
绘制
*************
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
*************
注意到
li.extend(i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in range(2,ni+1))
做的事情和
li = [ i*'*' + (2*(ni-i) - 1)*' ' + (i - i//ni)*'*'
for i in xrange(ni,0,-1)]
是一样的(少了一行),不过顺序是反的,我们可以简化一下:
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)
请注意
print '\n'.join(str(i) for i in xrange(500))
会立刻显示,因为程序在打印之前先计算了字符串 '\n'.join(str(i) for i in xrange(500)),然后一次性打印出来,而
for i in xrange(500):
print str(i)
显示起来要慢得多,因为计算机是一个接一个地打印500个字符串,每次调用 print 都比较耗时
。
还有另一种打印菱形的方法,我现在来写。
另外
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)
-> 所有这些函数在 nl 为偶数时,都会生成 nl-1 行的菱形。
编辑
最后,我更喜欢的是:
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)
因为使用了就地扩展(用 extend 和 reversed),而且没有那个可怕的 (i - i//ni)*'*'
2
你已经知道怎么打印每一行了。现在最后一步是生成正确的数字序列,以便让打印的行能够正确显示。
l = range(10,1,-1)
l.extend(range(1,11))
for x in l:
print x*'*' + 2*(10-x)*' ' + x*'*'
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
********************
********* *********
******** ********
******* *******
****** ******
***** *****
**** ****
*** ***
** **
* *
** **
*** ***
**** ****
***** *****
****** ******
******* *******
******** ********
********* *********
********************
2
基本的想法是决定哪个循环应该在每一行的两边只打印一个星号。然后修改另一个循环,使其不打印那一行(也就是说,不以两颗星的行开始或结束)。
把
for x in range(1,11):
改成
for x in range(2,11):
另外,你可以去掉最后一行,因为第二个循环已经自己处理了x
的增加。
为了让代码更易读,我建议只使用一种类型的循环。
例如,你可以用这个方式写第一个循环(注意:这个循环不会运行x=1
的情况,所以你需要使用未修改过的第二个循环版本)。
for x in range(10, 1, -1):
print x* '*' + 2*(10-x)*' '+ x*'*'