【问题标题】:Bar Making - Python酒吧制作 - Python
【发布时间】:2014-06-09 01:46:17
【问题描述】:

我正在编写一个函数,它接受一个列表变量并返回对应于列表中每个数字的竖线。我只有一个简单的问题,真的。也许,我在这里遗漏了一些东西。

def vBarMaker(nums): # Helper Function
    output = "" 
    while nums != 0: 
        nums -= 1 
        output += "*"
        if nums == 0:
            return output

def vBarGraphify(nums):
for num in nums:
    print vBarMaker(num)

print vBarGraphify( [0,1,3,2] )
# ^ This returns 
#
# *
# ***
# **

# But I want it to return:

#     * 
#     * *
#   * * *

有人可以帮我编辑这个函数,让它返回 ^。提前致谢。

【问题讨论】:

  • 您要求使用竖线,但您得到的所有答案都是水平的。您的示例输出不明确。您能否澄清一下您是否希望这些条高并并排或宽且堆叠? (水平和垂直可能会让某些人感到困惑)
  • 预期的输出应该是一行。
  • 您是否介意 editing 您的问题是 [0, 1, 3, 2] 而不是 [0, 1, 2, 3] 的预期输出?
  • 看起来每个人都认为您只是想右对齐条形
  • 是的,我们认为他想右对齐,因为它第一次格式错误,看起来像那样。

标签: python for-loop while-loop


【解决方案1】:

如果您希望条形图是垂直的,那么每个打印行都需要考虑所有值,并且您需要与最大值一样多的行:

def vBarGraphify(nums):
    for row in vBarMaker(nums):
        print row


def vBarMaker(nums):
    outputs = []
    for value in xrange(max(nums), 0, -1): # start with max, loop to zero
        row = ''
        for num in nums:
            if num >= value:               # is inside the bar
                row += '*'
            else:
                row += ' '
        outputs.append(row)
    return outputs

vBarGraphify([0, 1, 2, 3, 10])

输出:

    *
    *
    *
    *
    *
    *
    *
   **
  ***
 ****

我添加了一个10 来证明这些条实际上是垂直的,这与所有其他答案不同...

【讨论】:

    【解决方案2】:
    def vBarGraphify(nums):
       for num in nums:
          print " {:>10}".format("*" * num)
    

    编辑:

    def vBarGraphify( cols):
       for row in range( max( cols ),0,-1 ) :
          for col in cols: 
              print " " if col < row else "*",
          print
    

    更多的 Python:

    def vBarGraphify( nums ) : 
       # create 2d array of horizontal graph 10 X 4
       original = [ [n < num for n in range(max(nums)) ] for num in nums ]   
       # rotate it 4 X 10
       rotated = zip(*original)
       # print each line.
       for line in rotated[::-1]: 
          print "".join( "*" if col else " " for col in line ) 
    

    From Here!

    【讨论】:

    • 这很好,很干净,非常 Pythonic。
    • 它很好很干净,但不幸的是不是 OP 要求的列
    • @mhlester 哎呀。是的,错过了。
    【解决方案3】:

    目前,您有一个循环,它会输出相应的星号,直到达到数字为止。您还需要考虑空格。我要做的是为与正在打印的星号的当前索引号相对的数字输出一个空格。

    这就是说,如果传入函数的列表是[1,2,3],那么在第一次迭代时,应该打印两个空格和一个*:' *',在下一次迭代中,应该打印一个空格和两个*打印:' **' 在第三次迭代中,应打印三个 *:'***'

    编辑:

    尽管corn3lius 的回答已经很棒了,但我还是继续编写了我的实现代码。我在此处包括了他的内容以及文档测试,以便您了解它是如何工作的。

    我的答案和corn3lius'的主要区别在于左侧的空格是硬编码在corn3lius'答案中的,而我的是根据给定列表中的最大数量生成的。

    def BarGraphify1(nums):
        '''
        see http://stackoverflow.com/a/23257715/940217
        >>> BarGraphify1([1,2,3])
                  *
                 **
                ***
        '''
        for num in nums:
            print " {:>10}".format("*" * num)
    
    
    def BarGraphify2(nums):
        '''
        >>> BarGraphify2([1,2,3])
          *
         **
        ***
        >>> BarGraphify2([1,3,2])
          *
        ***
         **
        '''
        output = []
        maxVal = max(nums)
        for n in nums:
            space = (maxVal-n)*' '
            asterisks = n*'*'
            output.append(space + asterisks)
        print '\n'.join(output)
    
    
    
    if __name__ == '__main__':
        import doctest
        doctest.testmod()
    

    编辑#2:

    现在我看到 OP 想要编辑中显示的列,我重新设计了我的解决方案以使用 numpy.transpose 函数。大部分内容保持不变,但现在我将整个内容视为行和列,然后转置二维数组以获得所需的列。

    import numpy
    def BarGraphify3(nums):
        '''
        >>> BarGraphify3([1,2,3])
          *
         **
        ***
        >>> BarGraphify3([1,3,2])
         * 
         **
        ***
        '''
        grid = []
        maxVal = max(nums)
        for n in nums:
            space = (maxVal-n)*' '
            asterisks = n*'*'
            grid.append(list(space + asterisks))
    
    
        cols = []
        for row in numpy.transpose(grid):
            cols.append(''.join(row))
        print '\n'.join(cols)
    

    【讨论】:

    • [1, 3, 2] 的输出是什么?查看编辑
    • @mhlester 我为[1,3,2] 添加了一个文档测试,输出与我预期的一样,但现在我看到了来自 OP 的编辑并注意到了差异。我会看看我能做什么
    【解决方案4】:

    你应该看看str.format。它将帮助您了解如何在右侧对齐文本

    【讨论】:

      猜你喜欢
      • 2019-05-02
      • 2014-01-10
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-30
      • 1970-01-01
      • 2014-07-24
      相关资源
      最近更新 更多