在使用python将值写入csv文件之前,请将其与字段名进行比较

在使用python将值写入csv文件之前,请将其与字段名进行比较,python,csv,dictionary,field-names,Python,Csv,Dictionary,Field Names,在我将其存储在csv文件中以检查正确的列之前,我使用此代码将值与其关联的字段名进行比较,因为每次我重新启动机器时,字典中传感器的顺序都会自动更改。这就是为什么我必须在将dict值存储到csv文件之前控制dict值的位置,否则我将得到一个混乱的csv文件,如下面的示例所示,该文件提供的值温度为1000[°C]亮度10[lux] import csv from datetime import datetime import os import time from collections import

在我将其存储在csv文件中以检查正确的列之前,我使用此代码将值与其关联的字段名进行比较,因为每次我重新启动机器时,字典中传感器的顺序都会自动更改。这就是为什么我必须在将dict值存储到csv文件之前控制dict值的位置,否则我将得到一个混乱的csv文件,如下面的示例所示,该文件提供的值温度为1000[°C]亮度10[lux]

import csv
from datetime import datetime
import os
import time
from collections import OrderedDict
from time import sleep


Datum = time.strftime("%Y-%m-%d")
Time = datetime.now().replace(microsecond=0).isoformat()

data = {'Stecker Energy': '2.37', 'Stromzaehler Strom L1 [A]': '0.0', '1OG Ultraviolet': '0.0','Stecker EG  Energie [kWh]': '4.3'}

filename = Datum + 'SOF.csv'
if not os.path.isfile(filename):
    outfile = open(filename, "w")
    lineKey = ""
    for x in data.keys():
        lineKey+= x + ","
    lineKey = 'Time '+ "," + lineKey[:-1]+"\n" # Delete last character and add new line
    outfile = open(filename, "a")
    outfile.write(lineKey)
    outfile.close()

#check first line of  fieldnames 
with open(filename,'r') as myFile:
    reader = csv.DictReader(myFile)
    fieldnames = reader.fieldnames
    myFile.close()
#Compare the values with their  keys (fieldnames)
with open(filename,'a') as outfile:
    lineValue = ""
    for sensor, value  in data.items():
        if sensor in data.items()==sensor in fieldnames:
            v = data[sensor]
            print("v", v)
            lineValue+= str(v) + "," 
    lineValue = Time + "," + lineValue[:-1] + "\n"
    print(lineValue)
    outfile.write(lineValue)
    outfile.close()
问题是,当我检查CSV文件时,我发现值写入了错误的列,这意味着Examlpe的字段名错误:

CSV文件中此问题的示例

CSV文本示例

时间,Stromzaehler Strom L1[A],Stecker能量,1OG紫外线,Stecker EG能量[kWh] 2017-11-21T17:56:10,2.37,0.0,0.0,4.3 2017-11-21T17:56:26,4.3,0.0,0.0,2.37 2017-11-21T17:56:28,0,0.0,2.37,4.3 2017-11-21T17:56:30,0,2.37,0.0,4.3

data = {'Stecker Energy': '', 'Stromzaehler Strom L1 [A]': '', '1OG Ultraviolet': '','Stecker EG  Energie [kWh]': ''}
我觉得这不对劲。如果您只想遍历所有字段名(而不是“时间”),并在
数据中添加与这些字段对应的值,同时对
数据中不存在的值也加上“n/a”,那么我建议执行以下操作:

with open(filename,'a') as outfile:
    lineValue = ""
    for fieldname in fieldnames[1:]: #skip the first one, since that's Time, which we have a custom value for already.
        v = data.get(fieldname, "n/a")
        lineValue += str(v) + ","
    lineValue = Time + "," + lineValue[:-1] + "\n"
    print(lineValue)
    outfile.write(lineValue)
    outfile.close()

额外建议:手动在值之间添加逗号是一种容易出错的方法。如果可能的话,使用
DictWriter
,它可以为您解决大多数格式问题

with open(filename,'a') as outfile:
    writer = csv.DictWriter(outfile, fieldnames)
    row = {}    
    for fieldname in fieldnames: #no need to skip Time here, we'll just overwrite it later.
        row[fieldname] = data.get(fieldname, "n/a")
    row["Time "] = Time
    writer.writerow(row)
如果您坚持不这样做,请至少将值存储在列表中,然后在末尾加入一次:

with open(filename,'a') as outfile:
    values = [Time]
    for fieldname in fieldnames[1:]:
        v = data.get(fieldname, "n/a")
        values.append(str(v))
    outfile.write(",".join(values) + "\n")

额外建议:如果这些解决方案在您不想要的行之间添加额外的空行,您可以使用
newline=”“
参数打开文件(如果使用Python 3):

。。。或者以二进制模式打开文件(如果使用Python 2):


请发布CSV文件的文本版本,而不是图像。@MartinEvans我编辑了我的帖子。您可以在上面找到一个文本版本示例,
数据
对象的内容是什么?也许您可以使用
csv.DictWriter
类,而不是通过添加逗号和换行符等手动构造输出数据。这大大降低了分隔符错误放置的可能性,也给了你的代码一种很好的对称感,因为它在上半部分已经使用了
DictReader
。当我运行你的代码时,
print(fieldnames)
显示了
['Time Temp-hyperty-Current']
,这看起来是错误的。列表应该有四项,而不是一项。如果您的输入文件不包含任何逗号,那么我认为您需要配置DictReader,以便它知道这一事实。
with open(filename,'a') as outfile:
    values = [Time]
    for fieldname in fieldnames[1:]:
        v = data.get(fieldname, "n/a")
        values.append(str(v))
    outfile.write(",".join(values) + "\n")
with open(filename,'a', newline="") as outfile:
with open(filename,'ab') as outfile: