比较CSV中的数据并基于字典查找打印更改

时间:2018-08-03 21:49:31

标签: python python-3.x csv

我正在尝试比较csv中的差异。

第一个csv:

Device,Priority
Device 1,High
Device 2,Low
Device 3,Medium
Device 4,HIGH
Device 5,Not Found

第二个CSV:

Device,Group 1,Group 2,Group 3,FQDN
Device 2,Operation group MEDIUM,Layer 1 group MEDIUM,Layer 2 group MEDIUM,Some FQDN
Device 3,Operation group LOW,Layer 1 group LOW,Layer 2 group LOW,Some FQDN
Device 1,Operation group HIGH,Layer 1 group HIGH,Layer 2 group HIGH,Some FQDN
Device 4,Alerts,Alerts,Alerts,Some FQDN
Device 5,Operation group LOW,Layer 1 group LOW, Layer 2 group LOW

我希望我的输出csv文件能够输出从第一个csv起仅更改后的更新优先级,并将它们打印到各自的组中。

相关组为:

  • 操作(第1组)
  • 第1层(第2组)
  • 第2层(第3组)。

此外,如果该组与 ALERTS 或其他某个组无关,那么它应该跳过该迭代,并且不应该打印设备或有关该设备的任何信息。

这是我的输出文件的外观:

Device,Group 1,Group 2,Group 3
Device 2,Operation group LOW,Layer 1 group LOW,Layer 2 group LOW
Device 3,Operation group MEDIUM,Layer 1 group MEDIUM,Layer 2 group MEDIUM

它跳过了设备4,因为它有一个不相关的组称为ALERTS,跳过了设备5,因为在第一csv中没有提到优先级,并且也跳过了设备1,因为第一csv和第二csv中的优先级相同。

所有组(行)在第二个csv中具有相同的优先级,但组名称不同(操作,第1层和第2层)

这是我到目前为止已经尝试的方法:我创建了2个类,并且创建了一个字典,该字典可以在匹配时查找组值:

d = {
    ('High', 'Operation group HIGH'): 'Operation group HIGH',
    ('High', 'Layer 1 group HIGH'): 'Layer 1 group HIGH',
    ('High', 'Layer 2 group HIGH'): 'Layer 2 group HIGH'
}

稍后在我的代码中,我已经说明了这一点,目前,我仅在测试以获取第1组:

for group in groups:
    if device.1stcsvname == group.2ndcsvname:
        try:
            user = d[device.priorities, group.MessageType1]
        except:
            user = 'Not Found'

然后我得到输出:

Device,Group 1
Device 1,Operation group HIGH
Device 2,Operation group LOW
Device 3,Operation group MEDIUM
Device 4,Not Found
Device 5,Not Found

编辑2: 我已经创建了代码,现在可以完美地打印第一组了,但是我也尝试将其他两个组打印出来。这是我更新的代码:

d = {
('High', 'High'):
        'Operation group HIGH',

    ('Medium', 'Medium'):
        'Layer 1 group Medium',

    ('Low', 'Low'):
        'Layer 2 group Low',
}
    def get_validgroups(self):
        if 'Operations group' not in self.MessageType1:
            return 'Not Found'
        else:
            return self.MessageType1

    def get_comparison(self):
        if device.priorities.upper() in group.get_validgroups():
            return ''
        else:
            return device.priorities

    def onlychanged(self):
        if group.get_validgroups() == 'Not Found':
            return ''
        else:
            return group.get_comparison()

    def finalchanged(self):
        if device.priorities == 'Not Found':
            return ''
        else:
            return group.onlychanged()
for device in devices: #looping through both csvs
for group in groups:
    if device.1stcsvname== group.2ndcsvname:
        if group.finalchanged() == '': continue
#output with csv writerow here

我知道这段代码太长了,可以缩短它的时间。请帮助大家!

1 个答案:

答案 0 :(得分:0)

最后弄清楚了我的代码:

import csv

d = {
    ('High', 'High'):
        'Operation group HIGH',

    ('Medium', 'Medium'):
        'Operation group MEDIUM',

    ('Low', 'Low'):
        'Operation group LOW',
}


class DevicePriority:
    def __init__(self, fqdn, priority):
        self.fqdn = fqdn
        self.priority = priority

    @property
    def priorities(self):
        return self.priority

    @property
    def fqdns(self):
        return self.fqdn


def initializefile(file):
    with open('1stcsv.csv', 'r') as f:
        return convertrows(csv.DictReader(f))


def convertrows(rows):
    return [DevicePriority(row['Device'], row['Priority']) for row in rows]

file = r"My\1stcsv.csv"
devices = initializefile(file)


class MHTs:
    def __init__(self, FQDN, MessageType1):
        self.FQDN = FQDN
        self.MessageType1 = MessageType1

    @property
    def devicename(self):
        return self.FQDN

    @property
    def MessageType1(self):
        return self.MessageType1

    def get_validgroups(self):
        if 'Operation' not in self.MessageType1:
            return 'Not Found'
        else:
            return self.MessageType1

    def get_comparison(self):
        if device.priorities.upper() in group.get_validgroups():
            return ''
        else:
            return device.priorities

    def onlychanged(self):
        if group.get_validgroups() == 'Not Found':
            return ''
        else:
            return group.get_comparison()

    def finalchanged(self):
        if device.priorities == 'Not Found':
            return ''
        else:
            return group.onlychanged()

    def finalmhts(self):
        return d[device.priorities, group.onlychanged()]

    def mht2(self):
        if group.get_comparison() == 'High':
            return 'Layer 2 group HIGH
        elif group.get_comparison() == 'Medium':
            return 'Layer 2 group MEDIUM'
        else: 
            group.get_comparison() == 'Low':
            return 'Layer 2 group LOW'

    def mht3(self):
        if group.get_comparison() == 'High':
            return 'Layer 3 group HIGH'
        elif group.get_comparison() == 'Medium':
            return 'Layer 3 group MEDIUM'
        else:
            group.get_comparison() == 'Low'
            return 'Layer 3 group LOW'


def initializefile2(file):
    with open('2ndcsv.csv', 'r', newline='') as i:
        return convertmhts(csv.DictReader(i))


def convertmhts(rows):
    return [MHTs(row['FQDN'], row['MHT_1']) for row in rows]

file = r"My\2ndcsv.csv"
groups = initializefile2(file)


with open('Output.csv', 'w', newline='') as csvoutput:
    fieldnames = ['Priority', 'FQDN', 'MHT_1', 'MHT_2', 'MHT_3']
    output = csv.DictWriter(csvoutput, fieldnames=fieldnames)
    output.writeheader()

for device in devices:
    for group in groups:
        if device.fqdn == group.devicename:
            if group.finalchanged() == '': continue
            with open('Output.csv', 'a', newline='') as csvoutput:
                output = csv.writer(csvoutput)
                output.writerows([[device.priority] + [device.fqdn] + [group.finalmhts()] + [group.mht2()] + [group.mht3()]])