【问题标题】:Python max length of j-th item across sublists of a list列表子列表中第 j 个项目的 Python 最大长度
【发布时间】:2014-08-22 19:09:23
【问题描述】:

我有一个列表,例如:

x = [['aaa', 'bb','ccc'], ['ophkn','h','aa']]

假设len(x[i]) 对于i 的所有有效值(上例中的0 和1)都相同。

现在,我需要构造一个列表,其中包含x 的每个子列表中第 j 项的最大长度。也就是说,我需要知道以下几点:

max(len(x[i][j])) 覆盖所有 i 的值,固定值为 j

因此,在上面的示例中,我将生成如下列表:

[5, 2, 3]

因为

max(len('aaa'),len('ophkn')) --> 5
max(len('bb'),len('h'))      --> 2
max(len('ccc'),len('aa'))    --> 3

我试图找到这些最大值的原因是我可以打印一个填充空间的表格,如下所示:

aaa    bb  ccc
ophkn  h   aa

所以,如果有人有一种优雅的方式打印x,使其以管状格式对齐,请分享!

【问题讨论】:

    标签: python text formatting


    【解决方案1】:

    使用zip() 是另一种方法:

    >>> [max(len(a), len(b)) for a, b in zip(*x)]
    [5, 2, 3]
    

    正如 Robb 在 cmets 中指出的那样,对任意数量的行执行此操作的通用且有效的方法是:

    [max(len(b) for b in a) for a in zip(*x)]
    

    【讨论】:

    • 我相信 OP 正在寻求任意行数的解决方案。
    • 我最喜欢这种方法,但要将其推广到任意数量的行,您可以使用最大的生成器:[max(len(b) for b in a) for a in zip(*x)]
    • 谢谢@Robb。更新了答案以反映这一点。
    【解决方案2】:

    在生成器表达式上使用max()。例如,给定j 等于 1:

    >>> x = [['aaa', 'bb','ccc'], ['ophkn','h','aa']]
    >>> j = 1
    >>> max(len(i[j]) for i in x)
    2
    

    或者,遍历j的所有值:

    >>> for j in xrange(3):
    ...     print max(len(i[j]) for i in x)
    ...
    5
    2
    3
    

    【讨论】:

      【解决方案3】:

      您可以使用带有 splat 的 zip,例如:

      x = [['aaa', 'bb','ccc'], ['ophkn','h','aa']]
      
      maxlens = map(len, (max(el, key=len) for el in zip(*x)))
      # [5, 2, 3]
      

      然后从结果中使用适当的str.format。

      【讨论】:

        【解决方案4】:

        我假设您希望所有输出都根据所有子列表中最长的字符串对齐:

        x = [['aaa', 'bb','ccc'], ['ophkn','h','aa']]
        
        max(len(s) for y in x for s in y) # find length of longest string
        
        for x, y, z in x:
            print ("{0:<{1}} {2:<{3}} {4}".format(x, mx,y,mx ,z))
        aaa   bb    ccc
        ophkn h     aa
        

        您可以使用Format Specification Mini-Language 根据最长的字符串对齐文本。

        没有经过太多测试,但似乎适用于任意长度的行:

        x = [['aaa', 'bb','ccc',"guido"], ['ophkn','h','aa',"van"],["foo","bar","foobar","rossum"]]
        
        mx = max(len(s) for y in x for s in y)
        
        d = {"m":mx} # to pass as key because you can only have only named arguments after *exp
        for ele in x:
            print("".join("{:<{mx}} "*len(ele)).format(mx=d["m"],*tuple(ele)))
        
        aaa    bb     ccc    guido  
        ophkn  h      aa     van    
        foo    bar    foobar rossum 
        

        我们需要使用dict 来传递max length/mx,因为*tuple(ele) 后面不能有args,所以我们不能像第一个例子那样使用索引号,因为我们只会打印前两个子字符串.

        使用{:&lt;{mx}} 允许我们将嵌套的{} 设置为对齐参数。

        "".join("{:&lt;{mx}} "*len(ele) 根据行长度的需要创建尽可能多的格式{}。

        【讨论】:

        • 太棒了!它可以推广到任何长度的“行”吗?
        • 所有行的长度都一样吗?
        • 是的。所有将具有相同的长度。它将形成一个大的字符串矩阵(其中没有一个字符串有空格)。
        • @synaptik,我添加到我的答案中,看看它对你有什么影响
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多