我尝试在代码中使用 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,但是当我尝试此操作时,所有迭代的设备名称均为“无”,并且仅打印各个设备的第一个 IP。我想要的是打印所有的IP并且只打印一次它们对应的设备名称。我正在从 API 中提取这些数据。
seen = set()
seen_add = seen.add
for 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 None
10.23.54.6.8 None
10.23.6.1 None
10.22.16.34 None
10.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: Device1
Not Found
Device: Device2
Not Found
Device: Device3
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
我尝试过在 csv 文件上打印:
with open("BNA API.csv", 'w', newline='') as f:
fieldname = ['BNA Name', 'IP Addresses']
writer = csv.DictWriter(f, fieldnames=fieldname)
writer.writeheader()
for device in data:
fqdn = device['name']
if fqdn not in entries:
entries.add(fqdn)
print("\nDevice: %s" % fqdn)
for ips in device["dynamicFields"][0]["values"]:
try:
ipaddress.ip_address(ips)
print(ips)
except ValueError:
print("Not Found")
with open("BNA API.csv", 'a', newline='') as f:
writer = csv.writer(f)
writer.writerow([fqdn, ips])
这给了我输出:
BNA Name,IP Addresses
device1,Not Found
device2,Not Found
device3,10.228.143.125
device3,10.228.143.253
device3,10.229.184.125
device3,10.229.184.134
device3,192.21.247.125
device3,192.21.247.188
device3,192.21.247.226
在我的 CSV 上,我期待这样的输出:
BNA Name,IP Addresses
device1,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
device2,their ip addresses and so on..
IP 地址应位于第二列,并用一个空格分隔。 这是我的 JSON 结构:
[
{
"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"
],
}
]
}
]
这是一个此类设备的结构,我希望这是正确的,因为我无法放入所有参数,只能放入执行此代码所需的参数。 谢谢!
最佳答案
使用此数据集来测试代码:
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"])) 或 "not find"
正在检查 IPaddress 是否为空列表Python 的 True-y 检测意味着如果集合返回空,它将采用“未找到”
代替
编辑:
似乎这个问题还有更多内容,如果您的 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)
的函数,如果是则返回 True有效的 IP 地址,如果不是,则返回 false。
关于python - 在打印相应值时跳过特定迭代的重复值 - 我的最终目标是将其写入 CSV 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52303720/