Reputation: 13
I need to grab strings from all files in a directory and record them somehow, so I tried to use defaultdict to create this, but I'm having difficulty figuring out how to progressively add to each layer of the dictionary. Essentially, what the dictionary should look like is this:
Filename
Bundle
Info
Bundle
Info
Filename
Bundle
Info
etc I have the info as a list so I can just append anything I need onto the list, but when I run what I have here, I end up getting a single bundle and info for each file name. It seems like the update() function is replacing the values inside and I'm not sure how to make it keep adding and then creating a newer dictionary for each Bundle. Any help is appreciated, and sorry for any confusion.
import collections
import os
devices = collections.defaultdict(lambda: collections.defaultdict(dict))
# bundles = collections.defaultdict(dict)
for filename in os.listdir('.'):
if os.path.isfile(filename):
if '.net' in filename:
dev = open(filename)
for line in dev:
line = line.strip()
values = line.split(' ')
if values[0] == 'interface':
bundle_name = values[1]
if '/' in bundle_name:
pass
else:
if len(values) == 2:
ur_device = devices[filename]
ur_device.update(
{
'bundle_name': bundle_name,
'bundle_info': [],
}
)
if 'secondary' in values:
pass
elif values[0] == 'ipv4' and values[1] == 'address' and len(values) == 4:
ur_device['bundle_info'].append(
{
'ip_address': values[2],
'subnet_mask': values[3],
}
)
dev.close()
Upvotes: 1
Views: 7426
Reputation: 2073
A dictionary is something that has a key and a value, any time you put something into a dictionary that has the same key, it will replace that value. For instance:
dictionary = {}
# Insert value1 at index key1
dictionary["key1"] = "value1"
# Overwrite the value at index key1 to value2
dictionary["key1"] = "value2"
print(dictionary["key1"]) # prints value2
There are a few things that don't make sense about your code, but I suggest you use the above syntax for actually adding things to the dictionary (rather than the update method as that is used for adding a list of key/value pairs into a dictionary).
Below I marked up some suggestions to your code with #**'s
import collections
import os
#** I'm guessing you want to put your devices into this dict, but you never put anything into it
devices = collections.defaultdict(lambda: collections.defaultdict(dict))
# bundles = collections.defaultdict(dict)
for filename in os.listdir('.'):
if os.path.isfile(filename):
if '.net' in filename:
dev = open(filename)
for line in dev:
line = line.strip()
values = line.split(' ')
#** declare bundle_name out here, it is better form since we will make use of it in the immediate scopes below this
bundle_name = ''
if values[0] == 'interface':
bundle_name = values[1]
if '/' in bundle_name:
pass
else:
if len(values) == 2:
#** This is assuming you populated devices somewhere else??
devices[filename][bundle_name] = []
if 'secondary' in values:
pass
elif values[0] == 'ipv4' and values[1] == 'address' and len(values) == 4:
#** ur_device was not declared in this scope, it is a bad idea to use it here, instead index it out of the devices dict
#** it also might be worth having a check here to ensure devices[filename] actually exists first
devices[filename][bundle_name].append(
{
'ip_address': values[2],
'subnet_mask': values[3],
}
)
dev.close()
** Edit **
Looking at your question, you need to have multiple bundles for each filename. But your dictionary structure is not sufficiently detailed and you don't seem to provide the code for how you initialized devices with data.
Basically, you should think about what keys each level of the dictionary is going to have, not just what values.
devices (filename: device)
device (bundle_name?: info) <-- You are missing this dictionary
info (list that you append details to)
I changed the above code with my best guess as to what you intended.
Upvotes: 3