2017-04-12 2 views
0

Ich versuche, eine Datenstruktur aus einer CSV-Datei aufzubauen. Der Inhalt der CSV-Datei ist unten aufgeführt.So initialisieren Sie die Datenstruktur einmal in Python-Schleife

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

Ich versuche, die Daten von Gerätetyp zu einer Gruppe, dann Website und haben eine Liste von gemeinsamen IP-Adressen zusammen mit der Beschreibung.

Das Problem, das ich habe, ist, ich kann nicht arbeiten, um sicherzustellen, dass ich nur die verschiedenen Teile der Datenstruktur nur eine initialisiere.

Unten ist mein Code.

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) 

Was ich zur Zeit bin immer ist die folgende, die ist, weil mein außer immer auslöst ich

{ '‘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

Der üblicher Weg, um damit umzugehen ist 'defaultdict (dict)' zu verwenden (von 'collections') automatisch auf initiallze fehlende Schlüssel oder beim Check manuell' wenn my_item nicht in my_dict: my_dict [my_item] = {} 'vor dem Hinzufügen zum Diktat (oder Liste oder ...) – Julien

Antwort

1

Anhebung eine Ausnahme nützlich ist, zu zeigen, was eigentlich falsch ist. Als ich das tat, sah ich KeyErrors, so habe ich diesen Ansatz:

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) 

Beachten Sie, dass ich alle Schlüssel erschaffe, Listen oder dicts, die vor dem Versuch gebraucht werden, mit ihnen zu arbeiten. Das gibt mir die folgende Ausgabe:

{ '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

hier ein Ansatz glauben ist die .setdefault Methode. Wenn es in einer Schleife verwendet wird, tut es genau das, wonach Sie fragen: Es initialisiert den Wert, wenn der Schlüssel nicht existiert, andernfalls gibt er den gespeicherten Wert zurück. Ich persönlich mag es, aber ich kann sehen, wie andere dies nicht tun, weil es geschachtelte Lookups ein bisschen schwieriger zu lesen macht. Es ist eine Frage des Geschmacks:

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) 

Drucke:

{'‘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

Dieses wie eine nützliche Zeit scheint Pandas zu verwenden.

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

Verwandte Themen