关于Python 2.7:Python 2.7 – 在将CSV转换为JSON后,我得到了错误的值顺序

Python 2.7 - I'm getting the wrong order of values after converting CSV to JSON

本问题已经有最佳答案,请猛点这里访问。

我想通过从stdin获取数据并将其输出到stdout,将csv转换为json文件。输入数据的格式(每行)如下:11111 7_,B8:27:eb:da:ef:6d,0,B8:27:eb:8f:ba:38192.168.1.10171110_163200,19,0,0562,18.7,50.1,开,关,44.065933697,-2.700629,X

我的python代码是:

1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python
import csv, json , sys

fieldnames = ("Time","MAC_ETH","IP_ETH","MAC_WiFi","IP_WiFi","Up_time","Winsen","ADC_2","ADC_3","VOC","Temp","Humidity","Internet","Lampa_UV","CPU_temp","Amph_P1","Amph_P2","PT100","Brak",)
reader = csv.DictReader(sys.stdin, fieldnames)

for row in reader:
    print(json.dumps(row, sys.stdout))
    sys.stdout.write('
'
)

我的输出如下:

1
{"ADC_2":"0","ADC_3":"0","Up_time":"171110_163200","MAC_WiFi":"b8:27:eb:8f:ba:38","CPU_temp":"44.0","Temp":"18.7","VOC":"562","PT100":"-2.700629","MAC_ETH":"b8:27:eb:da:ef:6d","Internet":"ON","Winsen":"19","Humidity":"50.1","Amph_P2":"3697","Amph_P1":"6593","IP_ETH":"0","Time":"111117_055958","Brak":"X","Lampa_UV":"OFF","IP_WiFi":"192.168.1.10"}

所以参数的名称和值都可以。但是,与输入字符串和fieldnames值中的顺序相比,参数的顺序是不同的。你能告诉我我做错了什么吗?

我在Synology上使用了python 2.7.12。


解决这个问题的方法是使用一个普通的csv.reader(),然后用每行构造一个OrderedDict()。然后可以将其传递给json.dumps()以维持订单:

1
2
3
4
5
6
7
8
9
10
from collections import OrderedDict
import csv, json, sys

fieldnames = ("Time","MAC_ETH","IP_ETH","MAC_WiFi","IP_WiFi","Up_time","Winsen","ADC_2","ADC_3","VOC","Temp","Humidity","Internet","Lampa_UV","CPU_temp","Amph_P1","Amph_P2","PT100","Brak",)

for row in csv.reader(sys.stdin):
    rowd = OrderedDict(zip(fieldnames, row))
    print(json.dumps(rowd, sys.stdout))
    sys.stdout.write('
'
)

这将为您提供如下输出:

1
{"Time":"111117_055958","MAC_ETH":"b8:27:eb:da:ef:6d","IP_ETH":"0","MAC_WiFi":"b8:27:eb:8f:ba:38","IP_WiFi":"192.168.1.10","Up_time":"171110_163200","Winsen":"19","ADC_2":"0","ADC_3":"0","VOC":"562","Temp":"18.7","Humidity":"50.1","Internet":"ON","Lampa_UV":"OFF","CPU_temp":"44.0","Amph_P1":"6593","Amph_P2":"3697","PT100":"-2.700629","Brak":"X"}


json/dict不保留键顺序。

在python>3.6中,dict默认支持保留键顺序。

但是,由于reader有一个.fieldnames命令,您可以执行以下操作(未测试):

1
2
3
4
for row in reader:
    print(json.dumps({f: row[f] for f in reader.fieldnames}, sys.stdout))
    sys.stdout.write('
'
)

或者只需使用您自己声明的域名:

1
2
3
4
for row in reader:
    print(json.dumps({f: row[f] for f in fieldnames}, sys.stdout))
    sys.stdout.write('
'
)