将多个值分配给单个字典键 python

Assigning multiple values to a single dictionary key python

我正在尝试将重复 FIX 标记值分配给单个字典键。

我正在阅读的行包含多个具有不同值的 <269> FIX 标签:

<class 'list'>: ['8=FIX.X.X', '9=XXX', '35=V', '34=XXXXXX', '49=XXX.XXXXX.X', '56=XXX.XXXXX', '52=XXXXXXXX-XX:XX:XX.XXX', '128=XXXX,XXXX', '262=XXX/XXX-XXXXXXXXXX', '263=X', '265=X', '1021=X', '264=X', '267=X', '269=0', '269=1', '146=X', '55=XXX/XXX', '167=XXXXX', '1300=X', '63=X', '10=XXX']

每次我 运行 我的代码 269: 0 都被 269: 1 覆盖,我正在寻找一种方法将两个值附加到同一个键“269: 0,1”(不幸的是'无法找到我在类似问题线程上理解的方法)。

这是我的代码:

import os
import time
import csv

csvPath = 'C:/""/""/""/""/FixTakerLogs/'
logsPath = 'C:/""/""/""/""/FixTakerLogs/'

print('[START]:', 'MsgMarketDataRequest.csv')
fileMarketDataRequest = open('C:/Users/apanasenko/Desktop/LOGS/FixTakerLogs/MsgMarketDataRequest.log','r')
with open(csvPath + 'MsgMarketDataRequest.csv', 'w', newline='') as csvLogon:
    msgDict = {'8': '','9': '','35': '','49': '','56': '','34': '','52': '','128': '','262': '','263': '','264': '',
                 '265': '','267': '','269': '','146': '','55': '','167': '','63': '','12008': '','64': '','193': '',
                 '271': '','1201': '','1202': '','1300': '','10': ''}
    csvWriter = csv.DictWriter(csvLogon, msgDict.keys())
    csvWriter.writeheader()
    for line in fileMarketDataRequest:
        line = line.rstrip()
        line = line.split(';')
        X = len(line) - 1
        line = line[0:X]
        for tag in line:
            tag = tag.split('=')
            msgDict[tag[0]] = tag[1]
        csvWriter.writerow(msgDict)
        msgDict = {}
csvLogon.close()
print('[END]:', 'MsgMarketDataRequest.csv')

谢谢。

你可能熟悉这个列表?它是 Python 的可变多值存储,您可以迭代其中的所有值等等。例如,您的代码的一种可能替代方法是

msgDict = {'8': '','9': '','35': '','49': '','56': '','34': '','52': '','128': '','262': '','263': '','264': '',
             '265': '','267': '','269': '','146': '','55': '','167': '','63': '','12008': '','64': '','193': '',
             '271': '','1201': '','1202': '','1300': '','10': ''}

将使用由键值列表驱动的字典理解来使字典初始化更紧凑(并且希望更具可读性):

msg_dict = {key: '' for key in ['8', '9', '35', ... , '1'0']}

你会看到我更喜欢 PEP 8 中建议的命名风格,但风格并不像开始时编写工作代码那么重要 - 以后有足够的时间学习润色。这已经成为一种习惯,所以我想我会提一下。

按照类似的思路(尽可能编写可读代码总是最好的,所以这只是一个提示 - 它的工作方式与您的代码相同)您可以替换

X = len(line) - 1
line = line[0:X]

line = line[:-1]

不需要使用 len 函数,负索引就可以了,但如果您还没有遇到过它,那么值得了解一下。

代码的关键部分是读取

for tag in line:
    if tag not in line:
        tag = tag.split('=')
        msgDict[tag[0]] = tag[1]

最后的分配保证覆盖任何现有密钥。但是您可以通过将 msg_dict 的值初始化为空列表来使用值列表,如下所示:

msg_dict = {key: [] for key in ['8', '9', '35', ... , '1'0']}

并在找到标签后附加标签:

for tag in line:
    name, val = tag.split('=')
    if name in msgDict:
        msgDict[name].append(val)

您会看到我使用了 "unpacking assignment" 这样我就可以使用名称而不是索引 - 同样,这种技术有助于提高可读性。当您遍历所有标签后,msgDict 中的每个键将是遇到的所有值的列表。

当然,您随后会遇到如何明智地将其写入 CSV 文件以便您可以读回的问题(提示:您不必对所有内容都使用 CSV 文件!)。但我希望这是某种进步。祝你好运!

尝试像这样将列表放入字典中:

>>> from collections import defaultdict
>>> msg = defaultdict(list)
>>> for key, value in [(1, 2), (3, 4), (1, 3), (3, 5)] :
...     msg[key].append(value)
... 
>>> dict(msg)
{1: [2, 3], 3: [4, 5]}
>>>

您可以在下面找到适合我的代码:

import os
import time
import csv

csvPath = 'C:/'
logsPath = 'C:/'

print('[START]:', 'MsgMarketDataRequest.csv')
fileMarketDataRequest = open('C:/','r')
with open(csvPath + 'MsgMarketDataRequest.csv', 'w', newline='') as csvMarketDataRequest:
    msgDict = {key: [] for key in ['8', '9', '35', '49','56','34','52','128','262','263','264','265','267','269','146','55','167','63','12008','64','193','271','1201','1202','1300','10']}
    csvWriter = csv.DictWriter(csvMarketDataRequest, msgDict.keys())
    csvWriter.writeheader()
    for line in fileMarketDataRequest:
        line = line.rstrip()
        line = line.split(';')
        X = len(line) - 1
        line = line[0:X]
        for tag in line:
            name, val = tag.split('=')
            if name in msgDict:
                msgDict[name].append(val)
        csvWriter.writerow(msgDict)
        msgDict = {key: [] for key in ['8', '9', '35', '49','56','34','52','128','262','263','264','265','267','269','146','55','167','63','12008','64','193','271','1201','1202','1300','10']}
csvMarketDataRequest.close()
print('[END]:', 'MsgMarketDataRequest.csv')

感谢您的帮助。