【问题标题】:Python formatting a table through loop with a guide listPython通过带有指南列表的循环格式化表格
【发布时间】:2018-10-16 08:25:07
【问题描述】:

我在下面有一个标签列表。

mytags = ["a", "b", "c", "d", "e", "f"]

而且,我有一个文件,其中包含这样的列表格式的字符串。

['a-1',   'b-3',  'c-4',  'e-3']
['a-10', 'b-12', 'c-14', 'd-16']
['b-1',   'c-5', 'd-13',  'f-7']

我想像这样按照 mylist 中标签的顺序将文件打印为制表符分隔的表格。

#header
#a,   b,   c,   d,   e,  f
 a-1  b-3  c-4  NA   e-3 NA
 a-10 b-12 c-14 d-16 NA  NA
 NA   b-1  c-5  d-13 NA  f-7

我写了一个 python 代码,但是嵌套的双循环给出了一个不需要的结果。

print (mylist)

for lineList in file:
    for tag in mytags:
        if tag in lineList:
            print(lineList, end="\t")
        else:
            print("NA", end="\t")

如何用这些数据制作表格?

【问题讨论】:

  • 你考虑过熊猫吗?使用数据框的格式非常好,它将为您提供在预期输出中注释的标题和列名称。如果没有,您将不得不使用格式。这里有很多例子:pyformat.info 或者在这个与你有一些相似之处的问题中:stackoverflow.com/questions/4440516/…
  • "但是嵌套的双循环会产生不想要的结果。"

标签: python list loops for-loop


【解决方案1】:

在与标签列表进行比较之前,您应该从项目中提取标签:

mytags = ["a", "b", "c", "d", "e", "f"]
rows = [
    ['a-1',   'b-3',  'c-4',  'e-3'],
    ['a-10', 'b-12', 'c-14', 'd-16'],
    ['b-1',   'c-5', 'd-13',  'f-7']
]
for row in rows:
    for tag in mytags:
        print(row.pop(0) if row and row[0].split('-')[0] == tag else 'NA', end='\t')
    print()

或使用生成器表达式:

print('\n'.join('\t'.join(row.pop(0) if row and row[0].split('-')[0] == tag else 'NA' for tag in mytags) for row in rows))

【讨论】:

  • 您可以使用collection.defaultdict 使其更简单。
【解决方案2】:

可以在这里使用setdefault

my_tags = ["a", "b", "c", "d", "e", "f"]
line_list = [
    ['a-1',   'b-3',  'c-4',  'e-3'],
    ['a-10', 'b-12', 'c-14', 'd-16'],
    ['b-1',   'c-5', 'd-13',  'f-7']
]

for lst in line_list:
    d = {i[0]: i for i in lst}
    for i in my_tags:
        print(d.setdefault(i, 'NA'), end ='\t')
    print()


a-1     b-3     c-4     NA      e-3     NA  
a-10    b-12    c-14    d-16    NA      NA  
NA      b-1     c-5     d-13    NA      f-7 

【讨论】:

  • 如果我从外部导入 line_list,那么最后一行会丢失。到目前为止,一旦问题得到解决,这看起来是最好的答案。非常感谢您提供的漂亮代码。
  • @Karyo 欢迎您,希望一切正常,嗯,想不出为什么会这样,您能否将所有内容从外部加载到列表中然后执行此操作,但仍然应该可以工作,嗯
  • !哦,我的坏。忘记关闭写入功能。此代码完美运行。非常感谢!
  • @Karyo 我们去了,太棒了:)
【解决方案3】:

因为字符串将在一个文件中,所以下面是我的方法

# read the file
data = pd.read_csv('test.txt', header=None,sep='[')

master_df = pd.DataFrame(columns=['a','b','c','d','e','f'])

for i in range(len(data)):
    master_df.loc[i] = 'NA'
    temp = data[1][i].replace(']','')
    temp = temp.replace("'",'')
    for char in temp.split(','):
        master_df[char.split('-')[0].strip()][i] = char

print(master_df)

输出

      a       b       c      d      e      f
0   a-1     b-3     c-4     NA    e-3     NA
1  a-10    b-12    c-14   d-16     NA     NA
2    NA     b-1     c-5   d-13     NA    f-7

【讨论】:

    【解决方案4】:

    这是使用re(正则表达式) 来执行您所描述的操作的一种易于理解且简单的方法,但是您应该只获取文件的文本,而无需像csv_reader 或其他任何特殊阅读,所以只需使用open 函数读取文件,让我们开始吧:-

    import re
    
    filetext = """['a-1',   'b-3',  'c-4',  'e-3']
    ['a-10', 'b-12', 'c-14', 'd-16']
    ['b-1',   'c-5', 'd-13',  'f-7']"""
    
    #find all values
    values = re.findall(r'\w+-\d+', filetext)
    values.sort()
    
    #find tags
    tags = []
    for i in values:
        if(tags.count(i.split('-')[0])==0):
            tags.append(i.split('-')[0])
    
    #find max length
    maxLength = max([len(list(filter(lambda a:a.split('-')[0]==i, values))) for i in tags])
    
    #create a list with the results
    result = [[] for i in tags]
    ind=-1
    for i in tags:
        ind+=1
        for j in values:
            if(j.split('-')[0]==i):
                result[ind].append(j)
    
    #add 'NA' for non complete lists
    for i in result:
        i.sort(key=lambda v:int(v.split('-')[1]))
        if(len(i)!=maxLength):
            for j in range(maxLength - len(i)):
                i.append('NA')
    
    #print them as you liked
    for i in tags:
        print(i, end='\t')
    
    print()
    
    for i in range(maxLength):
        for j in result:
            print(j[i], end='\t')
        print()
    

    结果

    a      b      c      d       e      f    
    a-1    b-1    c-4    d-13    e-3    f-7    
    a-10   b-3    c-5    d-16    NA     NA   
    NA     b-12   c-14   NA      NA     NA
    

    【讨论】:

    • 感谢您的建议,但结果与我想要的不符。值应该在同一行,而不是其他行。
    猜你喜欢
    • 2016-08-28
    • 2018-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2021-03-29
    • 2017-05-17
    相关资源
    最近更新 更多