2017-04-12 73 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