2017-04-12 97 views
0

我想从一个CSV文件构建一个数据结构。 CSV文件的内容如下。如何在python循环中初始化数据结构一次

‘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’ 

我想按设备类型,然后网站分组数据,并有一个普通的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

通常的方式来处理,这是使用'defaultdict(字典)'(从'collections')自动initiallze丢失的钥匙,或手动检查'如果my_item不my_dict:my_dict [my_item] = {}'在添加到字典(或列表或...)之前 – Julien

回答

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']}}} 
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

这似乎是使用熊猫有用的时间。

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) 

enter image description here