如何在python循环中初始化数据结构

时间:2017-04-12 04:07:15

标签: python list csv dictionary

我正在尝试从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']}}}

3 个答案:

答案 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)

enter image description here