2008-10-05 101 views
16

我試圖將字符串值列表輸出爲2列格式。將字符串列表變成「普通文本」的標準方法是使用string.join方法。但是,它只需要2個參數,所以我只能使用「\ n」來創建一個列。我認爲試圖做一個循環,只需在列之間添加一個選項卡即可,但邏輯無法正常工作。將文本列表格式化爲列

我發現一個ActiveState page,它有一個相當複雜的做法,但它是從4年前。現在有沒有簡單的方法來做到這一點?


編輯這裏是我想要使用的列表。

skills_defs = ["ACM:Aircraft Mechanic", "BC:Body Combat", "BIO:Biology", 
    "CBE:Combat Engineer", "CHM:Chemistry", "CMP:Computers", 
    "CRM:Combat Rifeman", "CVE:Civil Engineer", "DIS:Disguise", 
    "ELC:Electronics","EQ:Equestrian", "FO:Forward Observer", 
    "FOR:Forage", "FRG:Forgery", "FRM:Farming", "FSH:Fishing", 
    "GEO:Geology", "GS:Gunsmith", "HW:Heavy Weapons", "IF:Indirect Fire", 
    "INS:Instruction", "INT:Interrogation", "JP:Jet Pilot", "LB:Longbow", 
    "LAP:Light Aircraft Pilot", "LCG:Large Caliber Gun", "LNG:Language", 
    "LP:Lockpick", "MC:Melee Combat", "MCY:Motorcycle", "MEC:Mechanic", 
    "MED:Medical", "MET:Meterology", "MNE:Mining Engineer", 
    "MTL:Metallurgy", "MTN:Mountaineering", "NWH:Nuclear Warhead", 
    "PAR:Parachute", "PST:Pistol", "RCN:Recon", "RWP:Rotary Wing Pilot", 
    "SBH:Small Boat Handling","SCD:Scuba Diving", "SCR:Scrounging", 
    "SWM:Swimming", "TW:Thrown Weapon", "TVD:Tracked Vehicle Driver", 
    "WVD:Wheeled Vehicle Driver"] 

我只是想輸出這個列表成簡單的2列格式以減少空間。理想情況下,列之間應該有標準空間,但我可以使用它。

ACM:Aircraft Mechanic  BC:Body Combat 
BIO:Biology   CBE:Combat Engineer 
CHM:Chemistry  CMP:Computers 
CRM:Combat Rifeman  CVE:Civil Engineer 
DIS:Disguise   ELC:Electronics 
EQ:Equestrian   FO:Forward Observer 
FOR:Forage   FRG:Forgery 
FRM:Farming    FSH:Fishing 
GEO:Geology    GS:Gunsmith 
HW:Heavy Weapons  IF:Indirect Fire 
INS:Instruction    INT:Interrogation 
JP:Jet Pilot   LB:Longbow 
LAP:Light Aircraft Pilot  LCG:Large Caliber Gun 
LNG:Language   LP:Lockpick 
MC:Melee Combat   MCY:Motorcycle 
MEC:Mechanic   MED:Medical 
MET:Meterology  MNE:Mining Engineer 
MTL:Metallurgy  MTN:Mountaineering 
NWH:Nuclear Warhead  PAR:Parachute 
PST:Pistol   RCN:Recon 
RWP:Rotary Wing Pilot  SBH:Small Boat Handling 
SCD:Scuba Diving  SCR:Scrounging 
SWM:Swimming  TW:Thrown Weapon 
TVD:Tracked Vehicle Driver WVD:Wheeled Vehicle Driver 
+0

您能否提供實際的輸入值和預期的輸出格式?不清楚你的輸入列表是什麼樣的。 – 2008-10-06 00:59:49

回答

0
data = [ ("1","2"),("3","4") ] 
print "\n".join(map("\t".join,data)) 

不夠靈活的ActiveState的解決方案,但是更短的:-)

+0

這並沒有解決問題,只是插入製表符將導致列內容寬度變化時(如在OP的'壞'輸出示例 – sidewinderguy 2014-11-19 21:34:24

+1

@sidewinderguy但它很短:-) – 2014-11-20 09:19:47

+1

它是非常短的:) – sidewinderguy 2014-11-22 02:09:58

11

兩列,由製表符分隔,連接成線。查看itertools以獲得等效的迭代器,以實現節省空間的解決方案。

import string 
def fmtpairs(mylist): 
    pairs = zip(mylist[::2],mylist[1::2]) 
    return '\n'.join('\t'.join(i) for i in pairs) 

print fmtpairs(list(string.ascii_uppercase)) 

A B 
C D 
E F 
G H 
I J 
... 

哎呀......被S.Lott抓住了(謝謝)。

更通用的解決方案,可處理任意數量的列和奇數列表。從S.lott略微修改,使用發電機來節省空間。

def fmtcols(mylist, cols): 
    lines = ("\t".join(mylist[i:i+cols]) for i in xrange(0,len(mylist),cols)) 
    return '\n'.join(lines) 
+0

可悲的是,這不適用於奇數的元素。 – 2008-10-06 10:33:00

+0

第二部分很棒! – Richard 2012-10-07 12:25:03

3

它很囉嗦,所以我將它分成兩部分。

def columns(skills_defs, cols=2): 
    pairs = [ "\t".join(skills_defs[i:i+cols]) for i in range(0,len(skills_defs),cols) ] 
    return "\n".join(pairs) 

它顯然可以作爲一個單一的loooong語句來完成。

這也適用於奇數的技能。

0

format_columns函數應該做你想要什麼:

from __future__ import generators 
try: import itertools 
except ImportError: mymap, myzip= map, zip 
else: mymap, myzip= itertools.imap, itertools.izip 

def format_columns(string_list, columns, separator=" "): 
    "Produce equal-width columns from string_list" 
    sublists= [] 

    # empty_str based on item 0 of string_list 
    try: 
     empty_str= type(string_list[0])() 
    except IndexError: # string_list is empty 
     return 

    # create a sublist for every column 
    for column in xrange(columns): 
      sublists.append(string_list[column::columns]) 

    # find maximum length of a column 
    max_sublist_len= max(mymap(len, sublists)) 

    # make all columns same length 
    for sublist in sublists: 
     if len(sublist) < max_sublist_len: 
      sublist.append(empty_str) 

    # calculate a format string for the output lines 
    format_str= separator.join(
     "%%-%ds" % max(mymap(len, sublist)) 
     for sublist in sublists) 

    for line_items in myzip(*sublists): 
     yield format_str % line_items 

if __name__ == "__main__": 
    skills_defs = ["ACM:Aircraft Mechanic", "BC:Body Combat", "BIO:Biology", 
     "CBE:Combat Engineer", "CHM:Chemistry", "CMP:Computers", 
     "CRM:Combat Rifeman", "CVE:Civil Engineer", "DIS:Disguise", 
     "ELC:Electronics","EQ:Equestrian", "FO:Forward Observer", 
     "FOR:Forage", "FRG:Forgery", "FRM:Farming", "FSH:Fishing", 
     "GEO:Geology", "GS:Gunsmith", "HW:Heavy Weapons", "IF:Indirect Fire", 
     "INS:Instruction", "INT:Interrogation", "JP:Jet Pilot", "LB:Longbow", 
     "LAP:Light Aircraft Pilot", "LCG:Large Caliber Gun", "LNG:Language", 
     "LP:Lockpick", "MC:Melee Combat", "MCY:Motorcycle", "MEC:Mechanic", 
     "MED:Medical", "MET:Meterology", "MNE:Mining Engineer", 
     "MTL:Metallurgy", "MTN:Mountaineering", "NWH:Nuclear Warhead", 
     "PAR:Parachute", "PST:Pistol", "RCN:Recon", "RWP:Rotary Wing Pilot", 
     "SBH:Small Boat Handling","SCD:Scuba Diving", "SCR:Scrounging", 
     "SWM:Swimming", "TW:Thrown Weapon", "TVD:Tracked Vehicle Driver", 
     "WVD:Wheeled Vehicle Driver"] 

    for line in format_columns(skills_defs, 2): 
     print line 

這是假設你有一個Python可用發電機。

3

這裏是由吉梅爾,這允許打印等間隔的列提供的解決方案的擴展。

def fmtcols(mylist, cols): 
    maxwidth = max(map(lambda x: len(x), mylist)) 
    justifyList = map(lambda x: x.ljust(maxwidth), mylist) 
    lines = (' '.join(justifyList[i:i+cols]) 
      for i in xrange(0,len(justifyList),cols)) 
    print "\n".join(lines) 

返回這樣的事情

ACM:Aircraft Mechanic BC:Body Combat
BIO:Biology CBE:Combat Engineer
CHM:Chemistry CMP:Computers
CRM:Combat Rifeman CVE:Civil Engineer
DIS:Disguise ELC:Electronics ......`

0

我想很多解決方案都混爲一談2分開東西int一個。

您希望:

  1. 能夠迫使一個字符串是一定的寬度
  2. 打印表格

這裏是一個非常簡單的拿上如何做到這一點:

import sys 

skills_defs = ["ACM:Aircraft Mechanic", "BC:Body Combat", "BIO:Biology", 
"CBE:Combat Engineer", "CHM:Chemistry", "CMP:Computers", 
"CRM:Combat Rifeman", "CVE:Civil Engineer", "DIS:Disguise", 
"ELC:Electronics","EQ:Equestrian", "FO:Forward Observer", 
"FOR:Forage", "FRG:Forgery", "FRM:Farming", "FSH:Fishing", 
"GEO:Geology", "GS:Gunsmith", "HW:Heavy Weapons", "IF:Indirect Fire", 
"INS:Instruction", "INT:Interrogation", "JP:Jet Pilot", "LB:Longbow", 
"LAP:Light Aircraft Pilot", "LCG:Large Caliber Gun", "LNG:Language", 
"LP:Lockpick", "MC:Melee Combat", "MCY:Motorcycle", "MEC:Mechanic", 
"MED:Medical", "MET:Meterology", "MNE:Mining Engineer", 
"MTL:Metallurgy", "MTN:Mountaineering", "NWH:Nuclear Warhead", 
"PAR:Parachute", "PST:Pistol", "RCN:Recon", "RWP:Rotary Wing Pilot", 
"SBH:Small Boat Handling","SCD:Scuba Diving", "SCR:Scrounging", 
"SWM:Swimming", "TW:Thrown Weapon", "TVD:Tracked Vehicle Driver", 
"WVD:Wheeled Vehicle Driver"] 

# The only thing "colform" does is return a modified version of "txt" that is 
# ensured to be exactly "width" characters long. It truncates or adds spaces 
# on the end as needed. 
def colform(txt, width): 
    if len(txt) > width: 
     txt = txt[:width] 
    elif len(txt) < width: 
     txt = txt + (" " * (width - len(txt))) 
    return txt 

# Now that you have colform you can use it to print out columns any way you wish. 
# Here's one brain-dead way to print in two columns: 
for i in xrange(len(skills_defs)): 
    sys.stdout.write(colform(skills_defs[i], 30)) 
    if i % 2 == 1: 
     sys.stdout.write('\n')