【问题标题】:How to print keys and values from dictionary with specific requirements如何从具有特定要求的字典中打印键和值
【发布时间】:2016-11-25 22:03:52
【问题描述】:
def main():
    salesData= readData('icecream.txt')
    print(salesData)
    #printReport(salesData)


# Reads the tabular data
# @param filename name of the input file
# @return a dictionary whose keys are ice cream flavors and whose values are sales data.

def readData(filename):
    # Create an empty dictionary.
    salesData={}

    infile=open(filename, "r")

    # Read each record from the file. 
    for line in infile:
        fields=line.split(":")  # what is field datatype
        flavor=fields[0]
        salesData[flavor]=buildList(fields)
        #print("SalesData", salesData)
        #print()
        #print()
    infile.close()
    return salesData

# Builds a list of store sales contained in the fields split from a string.
# @param fields a list of strings comprising the record fields
# @return a list of floating-point values

def buildList(fields):
    storeSales= []
    for i in range (1, len(fields)):
        sales=float(fields[i])
        storeSales.append(sales)
        #print('StoreSales', storeSales)
        #print()
    return storeSales

# Prints a sales report.
def printReport(salesData):
    numStores=0

#print the dictionary first without the totals?
#call print report


main()

当我以当前状态运行程序时,它会给我以下输出:

{'chocolate': [10225.25, 9025.0, 9505.0], 'strawberry': [9285.15, 8276.1, 8705.0], 'cookie dough': [7901.25, 4267.0, 7056.5], 'rocky road': [6700.1, 5012.45, 6011.0], 'vanilla': [8580.0, 7201.25, 8900.0]}

但是,我需要它看起来像这样:

chocolate    10225.25   9025.0      9505.0      Total: 28755.25
vanilla      8580.0     7201.25     8900.0      Total: 24681.25
rocky road   6700.1     5012.45     6011.0      Total: 17723.55
strawberry   9285.15    8276.1      8705.0      Total: 26266.25
cookie dough 7901.25    4267.0      7056.5      Total: 19224.75
           **42691.75   33781.8     40177.5**

干净、有条理、标签式、完美对齐。我不知道如何以干净的方式从字典中提取数据。此外,我还必须添加巧克力等的总数以及第 1、第 2 和第 3 列。介绍很重要。这不仅仅是“我如何输出数据”,而是“我如何以干净的呈现方式输出数据”。我正在考虑使用嵌套的 for 循环,或者可能是带有 for 循环的东西。但是那个 for 循环的去向,或者我如何使用它来干净地打印出字典数据,我希望它看起来像什么,这超出了我的范围。我查看了其他问题,但没有什么能比得上来自字典的数据的制表、组织和打印细节。我也尝试过经常引用的“for key, val in X.items():”,但这对我没有用。我什至不知道从哪里开始该功能及其令人难以置信的混乱。我会把它放在哪里?我该如何命名它?我会从那里去哪里?更不用说我有要添加的列和要添加的行。这是一个非常具体的问题。谢谢你。

【问题讨论】:

  • 我不知道那里发生了什么......
  • 彼得的答案没有解决列添加问题......而且,您的代码非常出色并且效果很好,只是没有添加列。我正在考虑(也许你可以在这里帮助我)将三列(col1、col2 和 col3)初始化为 0,然后 += 它们的值 [0] [1] 和 [2] 然后打印 print("\t\t", col1, "\t", col2, "\t", col3) 但是它不起作用:它不打印列的总和。只是其中一种口味。
  • 是的。我从您的建议中得到了我想要的输出,并且顺利运行它;但是,它只丢失了三个数字:42691.75 33781.8 40177.5。也就是说,我仍然不知道如何将每个键的 [0] 值相加成一个打印在相应列下方的数字(重复 [1] 值和 [2] 值)。
  • 好吧@ice cream,我的分站结束了。让我知道它是否适合你。

标签: python dictionary format output


【解决方案1】:

您可以使用 python 的string formatting 来创建常规外观。

有一个很好的网站与 python 格式化有关:https://pyformat.info

表格行的格式类似于:

>>> row = '{flavour}\t{sales[0]}\t{sales[1]}\t{sales[2]}\tTotal: {total}'

然后你可以填写字段:

>>> row.format(flavour='chocolate',
...            sales=[10225.25, 9025.0, 9505.0],
...            total=sum([10225.25, 9025.0, 9505.0]))
'chocolate    10225.25   9025.0      9505.0      Total: 28755.25'

要从字典中提取这些字段:

>>> for flavour, sales in salesData.items():
...     print(row.format(flavour=flavour,
...                      sales=sales,
...                      total=sum(sales)))
chocolate    10225.25   9025.0      9505.0      Total: 28755.25
vanilla      8580.0     7201.25     8900.0      Total: 24681.25
rocky road   6700.1     5012.45     6011.0      Total: 17723.55
strawberry   9285.15    8276.1      8705.0      Total: 26266.25
cookie dough 7901.25    4267.0      7056.5      Total: 19224.75

【讨论】:

  • 嘿,谢谢彼得。欣赏它。不过有几个问题:for 循环在哪里?是在salesData=readData('icecream.txt') 之后的def main(): 函数内吗?另外,如果可能的话,我想避免手动将数据携带到程序中。你看,我们的目标是让一个名为icecream.txt(包含字典信息)的文件中的信息直接输出为类似excel的格式。我应该能够将icecream.txt 替换为candy.txt 并以相同的格式输出,而无需手动将所有数据转移到核心porgram 中。
  • printReport 看起来是放置循环的好地方。此外,要将数据的文件名传递到您的脚本中,请参阅How can I pass a filename as a parameter into my module?,或者更好的是sys.argv[1] meaning in script
【解决方案2】:

Python 有一种出色的迷你语言,专门用于字符串格式化。这是应该使用的。

你知道你希望你的格式是

flavor sell1 sell2 sell3 Total: total sells

这相当于以下字符串格式:

"{} \t {} \t {} \t {} \t Total: {}"

既然您知道了自己的格式,下一步就是将此格式应用于字典中的每个 key, value 对。使用 for 循环遍历每个 key, value 对。

for key, value in dictionary.items():
    print("{} \t {} \t {} \t {} \t Total: {}".format(...))

剩下的最后一件事就是填空。你知道dict() 中的keys 是风味,所以format() 的第一个参数是key 变量:

.format(key, ...)

接下来,您需要来自key 值的三个值。我们可以索引value 中的每个值:

.format(key, value[0], value[1], value[2], ...)

这有点冗长,Python 有更好的方法。我们可以使用语法*iterable 简单地将值列表“解包”到适当的位置。

.format(key, *value, ...)

剩下的最后一个值就是你的总数。您可以使用内置函数sum()values 中的所有值相加:

.format(key, *value, sum(value))

现在要打印每列的总和,我们首先需要dict() 中每个键的值。这可以使用简单的列表推导来完成:

sales = [value for value in d.values()]

接下来,我们需要从sales 中的每个列表中获取第一个值并添加该值。这可以使用列表推导和 zip() 内置函数来完成:

totals = [round(sum(l), 1) for l in zip(*sales)]

round 函数与浮点数一起使用以将它们四舍五入到某个小数位。您可以根据自己的喜好更改该数字,但我选择了一个。剩下要做的最后一件事是打印每列的总数。经过一些实验,这应该可以正常工作:

`print("\t\t {}\t {}\t {}".format(*totals))

所以最终的解决方案是:

sales  = [value for value in d.values()]
    totals = [round(sum(l), 1) for l in zip(*sales)]
    for key, value in salesData.items():
        print("{} \t {} \t {} \t {} \t Total: {}".format(key, *value, sum(value)))
    print("\t\t {}\t {}\t {}".format(*totals))

【讨论】:

  • 谢谢!这对我有用。但是,我缺少一件事:如何输出各列下方的列的总和。 任何帮助将不胜感激。
  • 我收到一个错误,提示“d.values()”中的“d”未定义...这是为什么呢?谢谢!
【解决方案3】:

尝试以下方法:

def format_data(data):
    for item in data:
        print('{:15} {:15} {:15} {:15} {:10} Total:{:5}'.format(
            item, data[item][0], data[item][1], data[item][2], '',
            sum(data[item])))
    print('{:15} {:15} {:15} {:15}'.format('',
        sum(data[item][0] for item in data),
        sum(data[item][1] for item in data),
        sum(data[item][2] for item in data)))

输出:

>>> data = {'chocolate': [10225.25, 9025.0, 9505.0], 'strawberry': [9285.15, 8276.1, 8705.0], 'cookie dough': [7901.25, 4267.0, 7056.5], 'rocky road': [6700.1, 5012.45, 6011.0], 'vanilla': [8580.0, 7201.25, 8900.0]}

>>> format_data(data)
rocky road               6700.1         5012.45          6011.0            Total:17723.55
strawberry              9285.15          8276.1          8705.0            Total:26266.25
vanilla                  8580.0         7201.25          8900.0            Total:24681.25
cookie dough            7901.25          4267.0          7056.5            Total:19224.75
chocolate              10225.25          9025.0          9505.0            Total:28755.25
                       42691.75         33781.8         40177.5

【讨论】:

  • 我不太认为这是 OP 想要的。他的所有行都在前面对齐。
  • 输出正确,太好了!但我最大的抱怨是你巨大的单线。也许这些可以分解成更小的代码块? :)
  • 我在leaf给我的工作sn-p结束时给出了最后一行代码,但它说“数据”没有找到......
  • @icecream data 是您问题中的数据字典
【解决方案4】:
for key, value in salesData.items():
    print("{} \t {} \t {} \t {} \t Total: {}".format(key, *value, sum(value)))
print("\t", "{} \t {} \t {} \t {} \t".format('',
sum(salesData[value][0] for value in salesData),
sum(salesData[value][1] for value in salesData),
sum(salesData[value][2] for value in salesData)))

在 def main(): 中输入,您将获得所需的输出。

【讨论】:

    【解决方案5】:

    您可以使用库 outputformat 来帮助显示字典。

    pip install outputformat
    

    然后尝试以下操作:

    
    import outputformat as ouf
    
    d = {'chocolate': [10225.25, 9025.0, 9505.0], 'strawberry': [9285.15, 8276.1, 8705.0], 'cookie dough': [7901.25, 4267.0, 7056.5], 'rocky road': [6700.1, 5012.45, 6011.0], 'vanilla': [8580.0, 7201.25, 8900.0]}
    
    ouf.showdict(d, title="Ice cream flavours", style="box", precision=2)
    

    这应该会给你以下结果:

    ╭────────────────────╮
    │ Ice cream flavours │
    ├────────────────────╯
    ├ chocolate...: 10225.25, 9025.00, 9505.00
    ├ strawberry..: 9285.15, 8276.10, 8705.00
    ├ cookie dough: 7901.25, 4267.00, 7056.50
    ├ rocky road..: 6700.10, 5012.45, 6011.00
    ╰ vanilla.....: 8580.00, 7201.25, 8900.00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      相关资源
      最近更新 更多