【问题标题】:How to save a dictionary to a csv where each key has a different row如何将字典保存到每个键都有不同行的 csv
【发布时间】:2016-03-22 15:18:46
【问题描述】:
import time
import csv

def file_reader():
    product_location = {}
    location = 0
    with open('stockfile.csv', mode='r+') as f:
        reader = csv.reader(f)
        #next(reader) Can be included if I have headers to skip it
        products = {rows[0]: (rows[1],rows[2],rows[3],rows[4],rows[5]) for rows in reader}
        global products
    with open('stockfile.csv', mode='r+') as f:
        for line in f:
            lines = line
            print(lines)
            product_location[line.split(',')[0]] = location
            global product_location
        f.close()    

    total=0
    with open('stockfile.csv','r+') as f:
        for line in f:
            product_location[line.split(',')[0]] = location
            location += len(line)
total = 0
while True:
    file_reader()
    GTIN = input("\nPlease input GTIN or press [ENTER] to quit:\n")
    if GTIN == "":
        break
    if(GTIN not in products):
        print("Sorry your code was invalid, try again:")
        continue

    row = products[GTIN]
    description = row[0]
    value = row[1]
    stock = row[2]
    additional_stock = row[3]
    target_stock = row[4]

    print("Updating stock levels back to target level")
    stock = int(stock) + int(additional_stock)

    print('GTIN: ', GTIN)
    print('You have selected: ', description)
    print('The price of this product is: ', value)
    print('Stock: ', stock)

    quantity = input("Please input the quantity required: ")
    new_stock = int(stock) - int(quantity)

    if int(quantity) > int(stock):
        print("Sorry we don't have enough in stock please order again")
        print("Please try a different product or a smaller quantity: ")
        continue
    else:
        new_stock = int(stock) - int(quantity)
    if int(new_stock) < int(target_stock):
        answer = input("The stock is below target, if you would like to top up the product to the target stock level press [ENTER]")
        if answer == "":
            required = int(target_stock) - int(new_stock)
            added_stock = input("This is the target stock: %s, you must enter a minimum of %s" % (target_stock,required))
            stock= int(new_stock)+int(added_stock)
            while int(stock) < int(target_stock):
                print("Sorry input more please:")
                continue
            if int(stock) > int(target_stock):
                additional_stock = 0
                products[GTIN] = row[0],row[1],str(stock),str(additional_stock),row[4]
                print(products[GTIN])
                print(products)
                writer = csv.writer(open('stockfile.csv','w',newline=''))
                for key, row in products.items():
                    writer.writerow([key, value])

    else:
        additional_stock = int(target_stock) - int(new_stock)
        #I need to do the same here and change the dictionary and then send it to the CSV

        product_total = (int(quantity) * int(value))
    total = total + product_total
print('Total of the order is £%s' % total)

我无法弄清楚如何使用这种格式将字典发送回 csv(这是它在开始时被调用时的格式,我想以同样的方式发送回信息)。这就是库存文件的样子:This is the format I want the dictionary to be sent back in as well as when it is opened。 请同时发布有效的代码并提前感谢。

【问题讨论】:

  • 请提供MVCE:显示字典现在的样例,以及所需的输出csv(文本)。
  • @L3viathan 运行代码时会显示字典的示例,所需的输出是代码下注释中蓝色文本的格式(单击蓝色文字查看库存文件图片) .谢谢
  • @L3viathan 我明天真的需要这个代码,如果你能给我一种解决方案,我将非常感激,因为我真的需要帮助。如果您的代码正常运行,我非常感谢您。
  • 然后给我看(简略版)字典。我不想运行您的脚本,而且无论如何我都缺少要求。 StackOverflow 不是代码编写服务。

标签: python csv python-3.x dictionary export-to-csv


【解决方案1】:

根据您评论中的规范:

mydict = {'23456789': ('TV', '2000', '22', '0', '20'), '12345678': ('Fridge', '1000', '24', '0', '20'), '34567890': ('DVD', '10', '23', '0', '20')}

with open("out.csv", "w") as f:
    for key in mydict:
        f.write(key + "," + ",".join(mydict[key]))

【讨论】:

    【解决方案2】:

    我认为您的错误可能在您的“writer.writerow”行中,并且可能在字典键/值之间存在一些混淆。

    每个“writerow”都应该在每一行中编写一个一维列表。您在该行中定义为“行”的内容:

        for key, row in products.items():
    

    这实际上是字典keyvalue。是的,该值的数据类型恰好是一个列表(或一行),但该列表是字典 key 指向的 value

    您的代码不会尝试一次编写一个列表行。它实际上是在尝试将嵌套列表写入可视化电子表格中的每一行。这是因为您的 Dictionary Key 的 Value 本身就是一个 List 对象,它将一个列表放入另一个 writerow 列表中。

        [ KeyName  ,  ValueObject  ]
    

    由于我们的 ValueObject 是一个列表,因此我们在列表中拥有一个列表。

    使用您的示例 stockfile,这是大多数 python 文件阅读器解释的电子表格中每一行的样子:

        [ KeyName  ,  [ List, Of, Row, Values ] ]
    

    这是具有 2 个维度的嵌套列表。一行中只能写入 2 个电子表格单元格。解决这个问题的方法是确保“writer.writerow”一次只写一个一维列表。

    实现此目的的一种简单方法是将 2 个单独的列表连接到该行的 1 个单个列表中。

    但是,由于您将值标记为“行”并且将行项之一标记为“值”,如果我们坚持您的上下文,我们应该能够将该行值(这是一个列表)与与其关联的键名。

        for key, row in products.items():
            writer.writerow (  [ key ]  +  row  )
    

    由于在这种情况下您的“行”值变量已经是一个列表,我们可以简单地将字典键读取为它自己的列表对象,以便在一个列表(和 1 行)中轻松连接。

    那么 writerow 一次只写入 1 个列表,并且该列表中的每个项目都放置在 csv 文件中其自己的按时间顺序排列的单元格中。

    【讨论】:

    • 好的。您能否通过在错误出现之前确定您的键和值的类型来进行故障排除?在下面的for循环行“for key, value in products.items():”之后,请添加以下代码行:打印“Key Type:”,type(key),“Value Type:”,type(value)
    • 我们的最终目标是让 writerow 括号内的对象成为一维列表对象。如果该值是“str”类型,那么您最初是正确的。
    • 抱歉,我们中的任何一个人认为“行”和“值”之间存在一些混淆。我将编辑我的答案以反映您的代码,而不是我的解释。
    • 你能像我最近在回复中编辑的那样尝试再次更改 for 循环代码吗?
    • TypeError: can only concatenate list (not "tuple") to list 这是我得到的新错误
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多