【问题标题】:String formatting in Python with variable number argumentsPython中带有可变数字参数的字符串格式
【发布时间】:2018-01-03 07:44:14
【问题描述】:

我有一个dict,看起来像

A = {
    'test1':{'q0':[0.123,0.234],'phi0':[0.124,0.4325],'m':[9.42,0.3413]},
    'test2':{'q0':[0.343,0.353],'phi0':[0.2341,0.235]},
    'test3':{'q0':[0.343,0.353],'phi0':[0.2341,0.235],'m':[0.325,0.325],'z0':[0.234,0.314]}
    }

我想打印每个单独的字典:

'test1':                 q0=0.123(0.234) phi0=0.123(0.4325) m=9.42(0.3413)
'test2':                 q0=0.343(0.353) phi0=0.2341(0.235)
'test3': z0=0.234(0.314) q0=0.343(0.353) phi0=0.2341(0.235) m=0.325(0.325)

如何在 Python 3 中使用string.format() 做到这一点?由于每个子词典都有可变数量的“参数”,我不确定如何使用一些列表/词典理解来完成它。另外,如果我想在该参数丢失时留下一些空间,如所示,我该怎么做?每个字典最多有五个不同的参数 (q0,phi0,m,c,z0)。我将它打印到终端,所以我不需要很花哨的东西,但我希望它可以更具可读性。

【问题讨论】:

  • 您可以考虑编写一个函数,该函数将字典的键、值作为输入,并以所需格式返回输出并打印出来。
  • 您想要的部分是将子字典键按以下顺序排序:['z0','q0','phi0','m'] 通过自定义排序顺序或反向字母数字.您是否可以单独编写该代码,还是要将其粘贴在格式化代码中?

标签: python string python-3.x dictionary format


【解决方案1】:

请注意,字典是无序的数据结构,因此您不能期望在打印项目时有任何顺序,除非您使用它们的有序等效项collections.OrderedDict()。不过,您可以在 str.join() 方法中使用生成器表达式:

In [4]: for key, value in A.items():
    print(','.join(("{}: {}={}({})".format(key, t1,t2,t3) for t1, (t2, t3) in value.items())))
   ...:     
test1: q0=0.123(0.234),test1: phi0=0.124(0.4325),test1: m=9.42(0.3413)
test3: q0=0.343(0.353),test3: phi0=0.2341(0.235),test3: m=0.325(0.325),test3: z0=0.234(0.314)
test2: q0=0.343(0.353),test2: phi0=0.2341(0.235)

还请注意,由于我们正在执行以下内联解包,因此如果列表中的项目数多于/少于两个,它可能会引发 ValueError。

for t1, (t2, t3) in value.items()

因此,请确保解包变量的数量与列表中的项目数匹配。

【讨论】:

  • 除了 OP 的输出将子字典键排序为(反向字母数字?)顺序:['z0','q0','phi0','m']。缺失的元组显示为空白填充字段。
【解决方案2】:

由于您的测试和参数都在字典中,您可以先对它们进行排序以确保顺序一致。简单的排序可能不起作用,就像你有test13一样,默认情况下in会出现在test1之后。您可以使用 Python 库 natsort 来帮助解决此问题。

由于每组参数都可能缺少值,因此可以使用快速搜索来创建所有需要的cols 的列表。然后,您可以在打印缺少值的行时保留空间:

from natsort import natsorted

A = {
    'test1':{'q0':[0.123,0.234],'phi0':[0.124,0.4325],'m':[9.42,0.3413]},
    'test2':{'q0':[0.343,0.353],'phi0':[0.2341,0.235]},
    'test3':{'q0':[0.343,0.353],'phi0':[0.2341,0.235],'m':[0.325,0.325],'z0':[0.234,0.314]},
    'test13':{'q0':[0.343,0.353],'z0':[0.234,0.314]}
    }

sorted_tests = natsorted(A.items())     # Ensure test13 is numerical sorted correctly
# Create a list of all required cols
cols = set()

for test, params in sorted_tests:
    cols.update(params.keys())

cols = sorted(cols)    

for test, params in sorted_tests:
    row = [(col, params.get(col, [])) for col in cols]
    cells = []
    for p, values in row:
        if values:
            cells.append('{:20}'.format('{}={}({})'.format(p, values[0], values[1])))
        else:
            cells.append('{:20}'.format(''))

    print("{:6} : {}".format('{}'.format(test), ''.join(cells)))

这将为您提供以下输出:

test1  : m=9.42(0.3413)      phi0=0.124(0.4325)  q0=0.123(0.234)                         
test2  :                     phi0=0.2341(0.235)  q0=0.343(0.353)                         
test3  : m=0.325(0.325)      phi0=0.2341(0.235)  q0=0.343(0.353)     z0=0.234(0.314)     
test13 :                                         q0=0.343(0.353)     z0=0.234(0.314)

【讨论】:

    【解决方案3】:

    检查'z0' 是否在子词典的键中,并对这些项目应用与没有该键的项目稍有不同的字符串操作。看起来有点脏,但准确地产生了你的输出:

    for k,v in A.items():
        if 'z0' in v:
            print (k,":","{}={}({})".format('z0',v['z0'][0],v['z0'][1]), " ".join("{}={}({})".format(e,t[0],t[1]) for e,t in v.items() if 'z0' not in e))
        else:
            print (k,":                "," ".join("{}={}({})".format(e,t[0],t[1]) for e,t in v.items()))
    

    结果:

    test1 :                 q0=0.123(0.234) phi0=0.124(0.4325) m=9.42(0.3413)
    test2 :                 q0=0.343(0.353) phi0=0.2341(0.235)
    test3 : z0=0.234(0.314) q0=0.343(0.353) phi0=0.2341(0.235) m=0.325(0.325)
    

    注意:如果您确实需要tests 周围的那些单引号,即'test1' 而不是test1,您可以在两个print 中的k 的左右添加"'"我的陈述:print ("'",k,"'",...

    【讨论】:

      【解决方案4】:

      使用嵌套循环:

      for m,x in A.items():
          for y,z in x.items():
              print(m,'{0}='.format(y), z[0],'({0})'.format(z[1]))
      

      【讨论】:

        【解决方案5】:

        尝试以下基于 for 循环的代码,该循环产生排序输出:

        outlist = []
        for a in A:
            outstr = a+":"
            for aa in ('z0', 'q0','phi0','m','c'):
                if aa in A[a]:
                    outstr += aa+"="+str(A[a][aa][0])+"("+str(A[a][aa][1])+") "
                else:
                    outstr += "                "
            outlist.append(outstr)
        
        for i in sorted(outlist):
            print(i)
        

        输出:

        test1:                q0=0.123(0.234) phi0=0.124(0.4325) m=9.42(0.3413)                 
        test2:                q0=0.343(0.353) phi0=0.2341(0.235)                                 
        test3:z0=0.234(0.314) q0=0.343(0.353) phi0=0.2341(0.235) m=0.325(0.325)          
        

        【讨论】:

          【解决方案6】:

          试试这个:-

          A = {
              'test1':{'q0':[0.123,0.234],'phi0':[0.124,0.4325],'m':[9.42,0.3413]},
              'test2':{'q0':[0.343,0.353],'phi0':[0.2341,0.235]},
              'test3':{'q0':[0.343,0.353],'phi0':[0.2341,0.235],'m':[0.325,0.325],'z0':[0.234,0.314]}
              }
          for i,j in A.items():
              print i+':',
              for x,y in j.items():
                  print "{}= {}({})".format(x,y[0],y[1]),
              print 
          #output is same as expected
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-12
            • 2022-01-05
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多