我正在尝试从CSV文件构建数据结构。 CSV文件内容如下。
‘Windows 8’,10.1.1.1,’Windows 8 Server’,’SiteA’
‘Windows 8’,10.2.2.2,’Windows 8 Server’,’SiteB’
‘Cisco Router,’172.16.1.1’,’Cisco Router 881’,’SiteA’
‘Cisco Router,’172.16.1.3’,’Cisco Router 881’,’SiteC’
‘Cisco Router,’172.16.1.4’,’Cisco Router 881’,’SiteB’
我正在尝试按设备类型对数据进行分组,然后是Site,并列出常见的IP地址以及说明。
我遇到的问题是我无法确定我只是初始化数据结构的各个部分。
以下是我的代码。
import csv
import pprint
data = {}
pp = pprint.PrettyPrinter(indent=4)
f = open('/Users/marcos/Desktop/vulns/data.csv', 'rt')
try:
reader = csv.reader(f)
for row in reader:
product = row[0]
ip = row[1]
description = row[2]
site = row[3]
try:
data[product][site]['ipaddresses'].append(ip)
data[product][site]['description'] = description
except:
data[product] = {}
data[product][site] = {}
data[product][site]['ipaddresses'] = []
data[product][site]['ipaddresses'].append(ip)
data[product][site]['description'] = description
finally:
f.close()
pp.pprint(data)
我目前得到的是以下内容,这是因为我的除外总是触发我相信
{ '‘Cisco Router': { '’SiteB’': { 'description': '’Cisco Router 881’',
'ipaddresses': ['’172.16.1.4’']}},
'‘Windows 8’': { '’SiteB’': { 'description': '’Windows 8 Server’',
'ipaddresses': ['10.2.2.2']}}}
答案 0 :(得分:1)
以下是使用.setdefault
方法的方法。当在循环中使用时,它完全符合您的要求:如果该键不存在,则初始化该值,否则返回存储的值。
我个人喜欢它,但我可以看到其他人不喜欢它,因为它使嵌套查找更难阅读。这是一个品味问题:
reader = """
‘Windows 8’,10.1.1.1,’Windows 8 Server’,’SiteA’
‘Windows 8’,10.2.2.2,’Windows 8 Server’,’SiteB’
‘Cisco Router,’172.16.1.1’,’Cisco Router 881’,’SiteA’
‘Cisco Router,’172.16.1.3’,’Cisco Router 881’,’SiteC’
‘Cisco Router,’172.16.1.4’,’Cisco Router 881’,’SiteB’
"""
reader = [line.split(',') for line in reader.replace("'", '').strip().split('\n')]
data = {}
for row in reader:
product, ip, description, site = row[:4]
site_data = data.setdefault(product, {}).setdefault(site, {})
site_data.setdefault('ipaddresses', []).append(ip)
site_data['description'] = description
import pprint
pprint.pprint(data)
打印:
{'‘Cisco Router': {'’SiteA’': {'description': '’Cisco Router 881’',
'ipaddresses': ['’172.16.1.1’']},
'’SiteB’': {'description': '’Cisco Router 881’',
'ipaddresses': ['’172.16.1.4’']},
'’SiteC’': {'description': '’Cisco Router 881’',
'ipaddresses': ['’172.16.1.3’']}},
'‘Windows 8’': {'’SiteA’': {'description': '’Windows 8 Server’',
'ipaddresses': ['10.1.1.1']},
'’SiteB’': {'description': '’Windows 8 Server’',
'ipaddresses': ['10.2.2.2']}}}
答案 1 :(得分:1)
提出异常对于显示实际错误很有用。当我这样做时,我看到了KeyErrors,所以我使用了这种方法:
try:
reader = csv.reader(f)
for row in reader:
product = row[0]
ip = row[1]
description = row[2]
site = row[3]
try:
if product not in data:
data[product] = {}
if site not in data[product]:
data[product][site] = {}
if 'description' not in data[product][site]:
data[product][site]['description'] = description
if 'ipaddresses' not in data[product][site]:
data[product][site]['ipaddresses'] = []
data[product][site]['ipaddresses'].append(ip)
data[product][site]['description'] = description
except Exception, e:
raise
finally:
f.close()
pp.pprint(data)
请注意,在尝试使用它们之前,我正在创建所需的任何键,列表或词组。 这给了我以下输出:
{ 'Cisco Router': { 'SiteA': { 'description': 'Cisco Router 881',
'ipaddresses': ['172.16.1.1']},
'SiteB': { 'description': 'Cisco Router 881',
'ipaddresses': ['172.16.1.4']},
'SiteC': { 'description': 'Cisco Router 881',
'ipaddresses': ['172.16.1.3']}},
'Windows 8': { 'SiteA': { 'description': 'Windows 8 Server',
'ipaddresses': ['10.1.1.1']},
'SiteB': { 'description': 'Windows 8 Server',
'ipaddresses': ['10.2.2.2']}}}
答案 2 :(得分:1)
这似乎是使用熊猫的有用时间。
import pandas as pd
data_ = pd.read_csv('path-to-data.csv')
data_.columns = ['product', 'ip', 'description', 'site']
# Create a 'grouped' dataset object
grouped = df.groupby(['product', 'site', 'ip'])
# Create a dataset with a list of unique 'description' values,
# grouped by columns above
unique_desc_by_group = grouped['description'].aggregate(lambda x: tuple(x))
print(unique_desc_by_group)