为了账号安全,请及时绑定邮箱和手机立即绑定

在打印相应值时跳过特定迭代的重复值 - 我的最终目标是将其写入 CSV 文件

在打印相应值时跳过特定迭代的重复值 - 我的最终目标是将其写入 CSV 文件

烙印99 2021-06-07 16:46:14
我试图在我的代码中使用 set() 来跳过迭代中的重复值;此类问题可能已在 SO 上得到解答,但是当我尝试在我的脚本中执行此操作时,我没有得到所需的输出。我正在使用 device['name'] 提取设备名称,API 中的 IP 地址为;这是 IP 地址的此类设备的 API 响应主体:"DTO": [  {    "id": "3485893021",    "name": "Alternate Addresses",    "IPAddress": [      "10.228.143.125",      "10.228.143.253",      "10.229.184.125",      "10.229.184.134",      "192.21.247.125",      "192.21.247.188",      "192.21.247.226",      "192.21.247.254",      "192.21.247.61",      "192.21.247.92",      "192.168.53.38",      "192.128.167.74"     ]我有一个像上面一样的单个设备的多个 IP,但是当我尝试这个时,我将所有迭代的设备名称设为 None 并且只打印来自各个设备的第一个 IP。我想要的是打印所有 IP 并只打印一次它们对应的设备名称。我正在从 API 中提取这些数据。seen = set()seen_add = seen.addfor device in data:    fqdn = device['name']    for ips in device["DTO"][0]["IPaddress"]:        if fqdn not in seen:            print(ips, seen_add(fqdn))这是输出:10.228.143.125 None10.23.54.6.8 None10.23.6.1 None10.22.16.34 None10.122.25.189 None我在 python 控制台输出中期待这个:10.228.143.125 10.228.143.253 10.229.184.125 10.229.184.134 192.21.247.125 192.21.247.188 192.21.247.226 192.21.247.254 192.21.247.61 192.21.247.92 192.168.53.38 192.128.167.74 devicename1等等其他此类设备......更新:这个完全按照我想要的方式打印,但是现在当我尝试在 CSV 文件上打印它时,fqdn 和 ipaddresses 开始分崩离析。谁能帮助我以更简单的方式写这个?for device in data:    fqdn = device['name']    if fqdn not in entries:        entries.add(fqdn)        print("\nDevice: %s" % fqdn)    for ips in device["DTO"][0]["IPaddress"]:                try:                    ipaddress.ip_address(ips)                    print(ips)                except ValueError:                    print("Not Found")python控制台上的输出:Device: Device1Not FoundDevice: Device2Not FoundDevice: Device310.228.143.12510.228.143.25310.229.184.12510.229.184.134192.21.247.125192.21.247.188192.21.247.226我试过这个打印在一个 csv 文件上:with open("BNA API.csv", 'w', newline='') as f:    fieldname = ['BNA Name', 'IP Addresses']    writer = csv.DictWriter(f, fieldnames=fieldname)    writer.writeheader()
查看完整描述

3 回答

?
红糖糍粑

TA贡献1815条经验 获得超6个赞

使用这个数据集来测试代码:


data = [

  {

    "name": "device1",

    "vendorName": "Cisco",

    "DTO": [

      {

        "id": "426945997-254",

        "name": "Category",

        "IPaddress": [

          "10.228.143.125",

          "10.228.143.253",

          "10.229.184.125",

          "10.229.184.134",

          "192.21.247.125"

         ],

       }

     ]

   },

   {

    "name": "device2",

    "vendorName": "Cisco",

    "DTO": [

      {

        "id": "426945997-254",

        "name": "Category",

        "IPaddress": [


         ],

       }

     ]

   },

   {

    "name": "device3",

    "vendorName": "Cisco",

    "DTO": [

      {

        "id": "426945997-254",

        "name": "Category",


       }

     ]

   }

 ]

我不确定你到底在做什么,因为你的代码与键名不匹配,但这应该适合你


import csv 

with open("BNA API.csv", 'w', newline='') as f:

    fieldname = ['BNA Name', 'IP Addresses']

    writer = csv.DictWriter(f, fieldnames=fieldname)

    writer.writeheader()


with open("BNA API.csv", 'a', newline='') as f:

    for device in data:

        fqdn = device['name']   

        try:

            ips = ' '.join(set(device["DTO"][0]["IPaddress"])) or "not found"

        except KeyError:

            ips = "not found"


        writer = csv.writer(f)

        writer.writerow([fqdn, ips])

ips = ' '.join(set(device["DTO"][0]["IPaddress"])) or "not found"正在检查,如果IP地址为空的清单是用Python的True-Y检测的意义如果集合返回空它会采取"not found"替代


编辑:似乎这个问题还有更多内容,如果您的 IP 地址不正确或没有什么,您可以' '.join()像这样使用过滤器:


bad_list = ['Firewall','Load something']

#...

#same code


try:

    ips = ' '.join(x for x in set(device["DTO"][0]["IPaddress"]) if x not in bad_list) or "not found"

if x not in bad_list在将其添加到 之前的检查.join(),您可以将其视为在遍历列表时的过滤器。如果您不想键入要排除的所有内容,您可以将其更改为if ipaddress(x)并编写一个调用的函数ipaddress(x),如果它是有效的 ipaddress,则返回 True,如果不是,则返回 false。


查看完整回答
反对 回复 2021-06-16
?
德玛西亚99

TA贡献1770条经验 获得超3个赞

两个建议:

1) seen_add做了一些事情,但它不返回任何东西,这就是给你 None 的。

2)如果你不希望它们被换行分开,你不能在for循环中打印,你只需要一个打印。您可以随时构建字符串:out_str = out_str + ' ' + ips

如果你不关心顺序,一点点展平应该可以工作:

print(' '.join{ips for device in data for ips in device["DTO"][0]["IPaddress"]})


查看完整回答
反对 回复 2021-06-16
  • 3 回答
  • 0 关注
  • 191 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号