2012-12-14 64 views
3

對於問這個非常基本的問題,我很抱歉,但我真的被困在這裏了......我嘗試了使用Google搜索並使用搜索功能,但找不到我要找的東西。使用for-loop從列表中打印均勻間隔的表格

我試圖從對象列表中打印值的表。但是,由於「名稱」字符串的大小變化很大,它會使整個表格變形,使其幾乎無法讀取。我嘗試在\ t之間添加標籤,但列仍未對齊。有什麼我可以添加到這個打印聲明,使一個不錯的,直的表?

print "name","level","value" 
for i in self.items: 
    print i.name, i.lvl, i.value 

回答

2

如果您還沒有該項目的最大尺寸,從而無法使用的格式說明符,你可以計算出當前的最大長度和使用str.center(或str.rjust):

>>> from collections import namedtuple 
>>> Record = namedtuple('Record', ['name', 'lvl', 'value']) 
>>> items = [Record('a', 5, 1000), Record('aaaaaa', 15376576, 17.8), Record('aaaaaaaaaaaaaaaa', 7462, 1000)] 
>>> max_name_length = len(max(items, key=(lambda x: len(x[0])))[0]) 
>>> max_lvl_length = len(str(max(items, key=(lambda x: len(str(x[1]))))[1])) 
>>> max_value_length = len(str(max(items, key=(lambda x: len(str(x[2]))))[2])) 
>>> for item in items: 
...  print '%s %s %s' % (item.name.center(max_name_length), 
...       str(item.lvl).center(max_lvl_length), 
...       str(item.value).center(max_value_length)) 
... 
     a   5  1000 
    aaaaaa  15376576 17.8 
aaaaaaaaaaaaaaaa 7462 1000 
5

你可以試試是這樣的:

In [1]: headers = ["name","level","value"] 

In [2]: vals1 = ["Some long name", "a level", "a value"] 

In [3]: vals2 = ["An even longer name", "another level", "another value"] 

In [4]: max_lens = [len(str(max(i, key=lambda x: len(str(x))))) for i in zip(headers, vals1, vals2)] 

In [5]: for row in (headers, vals1, vals2): 
    ...:  print '|'.join('{0:{width}}'.format(x, width=y) for x, y in zip(row, max_lens)) 
    ...: 
    ...: 
name    |level  |value 
Some long name  |a level  |a value 
An even longer name|another level|another value 

此發現您的數據行的最大長度,並打印均勻間隔的表。在這種情況下,max_lens使用zip將給定'列'中的所有項目一起壓縮(例如,考慮name列中的所有項目)。然後,它會查找最長字符串的長度(正如@Bakuriu指出的那樣,如果任何字段不是字符串,這些字符串都需要轉換爲字符串)並將其存儲爲'列'的長度。然後在迭代中,您指定一個width,它將等於該'列'的最大長度,並傳入該行的該行的值(希望有意義:))。

format方法利用了非常強大的字符串格式化規範。這是一個非常基本的例子,但它可以修改以適應更多的動態情況(例如那些有很多行的情況等)。

至於如何使用您的數據的例子,你可以嘗試下面的例子。請注意,這不是最可讀的代碼(在Python裏是重要的),所以如果你是做同樣的事情,它可能是值得的實際編寫出一些for循環,使這是一個有點更明顯發生了什麼是怎麼回事(因爲正如我所說,這是一個有點混淆:)):

In [1]: class MyClass(object): 
    ...:  def __init__(self, a, b, c): 
    ...:   self.name = a 
    ...:   self.level = b 
    ...:   self.value = c 
    ...: 
    ...: 

In [2]: headers = ['name', 'level', 'value'] 

In [3]: vals1 = MyClass('Some long name', 'a level', 10348) 

In [4]: vals2 = MyClass('An even longer name', 'another level', 100008484) 

In [5]: items = (vals1, vals2) 

In [6]: item_lens = [[getattr(item, x) for x in headers] for item in items] 

In [7]: max_lens = [len(str(max(i, key=lambda x: len(str(x))))) for i in zip(*[headers] + item_lens)] 

In [8]: print '|'.join('{0:{width}}'.format(x, width=y) for x, y in zip(headers, max_lens)) 
name    |level  |value 

In [9]: for i in items: 
    ...:  print '|'.join('{0:{width}}'.format(x, width=y) for x, y in zip([getattr(i, x) for x in headers], max_lens)) 
    ...: 
    ...: 
Some long name  |a level  |10348 
An even longer name|another level|100008484 
+0

+1尼斯和整齊 –

+0

@ShawnZhang謝謝:) – RocketDonkey

+0

我喜歡'鍵=拉姆達X:LEN(X)': ) – khachik