Convert Text to Dict [repetitive key in textline] - python

I have sample text file as below
asy1 10.20.0.1
byt 192.1.10.100
byt 192.1.10.101
byt 192.1.10.102
hps 10.30.1.50
hps 10.30.1.53
hps 10.30.1.54
hps 10.30.1.55
hps 10.30.1.56
zte 10.100.1.1
zte 10.100.1.2
When i run script below
mydict = {}
with open('devices.txt', 'r') as file:
for line in file:
name, ip = line.split()
mydict[name] = ip.strip()
print(mydict)
It not return all the line/content as per text file.
{'hps': '10.30.1.56', 'zte': '10.100.1.2', 'byt': '192.1.10.102', 'asy1': '10.20.0.1'}
I miss something here...Please advise me. Thanks

In a dictionary the key must be uniques, when you do:
mydict[name] = ip.strip()
you overwrite the value, instead of having a single value for a key you could store a list of values, by doing this:
mydict = {}
with open('devices.txt', 'r') as file:
for line in file:
name, ip = line.split()
if name not in mydict:
mydict[name] = []
mydict[name].append(ip.strip())
print(mydict)
Output
{'asy1': ['10.20.0.1'], 'byt': ['192.1.10.100', '192.1.10.101', '192.1.10.102'], 'hps': ['10.30.1.50', '10.30.1.53', '10.30.1.54', '10.30.1.55', '10.30.1.56'], 'zte': ['10.100.1.1', '10.100.1.2']}
A second alternative would be to use setdefault instead:
mydict.setdefault(name, []).append(ip.strip())
A third option would be to use a defaultdict. If the values are unique consider using a set.

Many of those names are the same, but a dict can only have one value for a given key - if you try to add an IP to the dictionary with key hps, but there's already one in there, it will be overwritten. Maybe use a list instead?

Related

How can I open a txt as a dictionary?

I have the following txt... (I've saved as a dictionary)
"{'03/01/20': ['luiana','macarena']}\n"
"{'03/01/21': ['juana','roberta','mariana']}\n"
"{'03/01/24': ['pedro','jose','mario','luis']}\n"
"{'03/01/24': ['pedro','jose','mario','luis']}\n"
"{'03/01/22': ['emanuel']}\n"
the problem is that I want to open it as a dictionary, but I don't know how I can do it. I've tried with:
f = open ('usuarios.txt','r')
lines=f.readlines()
whip=eval(str(lines))
but it's not working... my idea is for example just take the dictionaries that have as a value the next day 03/01/24
if you want to to have only one dict with all the saved dictionaries you can use:
import ast
my_dict = {}
with open('your_file.txt', 'r') as fp:
for line in fp.readlines():
new_dict = ast.literal_eval(line)
for key, value in new_dict.items():
if key in my_dict:
my_dict[key].extend(value)
else:
my_dict[key] = value
print(my_dict)
output:
{'03/01/20': ['luiana', 'macarena'], '03/01/21': ['juana', 'roberta', 'mariana'], '03/01/24': ['pedro', 'jose', 'mario', 'luis', 'pedro', 'jose', 'mario', 'luis'], '03/01/22': ['emanuel']}
if yo could change the format you are saving the strings from
"{'03/01/20': ['luiana','macarena']}\n"
to
'{"03/01/20": ["luiana","macarena"]}\n'
Then you could just do the following:
import json
line = '{"03/01/20": ["luiana","macarena"]}\n'
d = json.loads('{"03/01/20": ["luiana","macarena"]}\n')
The result would be a dictionary d with dates as keys:
>>> {'03/01/20': ['luiana', 'macarena']}
Them, it would be just a mater of looping over the lines of your file and adding them to your dictionary.
An alternative approach would be to use pickle to save your dictionary instead of the .txt, them use it to load from the disk.

Two dimensional dictionary with list as a value python

I'm writing a simple parser for exercise and I have a problem with saving downloaded data to a dictionary.
data = {"":{"":[]}}
with open("Training_01.txt", "r") as open_file:
text = open_file.read()
text = text.split("\n")
for i in text:
i = i.split("/")
try:
data[i[1]] = {i[2]:[].append(i[3])}
except:
print("Can't")
This is an example of the data that I want to parse:
/a/abbey/sun_aobrvxdhumowzajn.jpg
/a/abbey/sun_apstfzmbeiwbjqvb.jpg
/a/abbey/sun_apyilcssuybumhbu.jpg
/a/abbey/sun_arrohcvipmrghrzh.jpg
/a/abbey/sun_asgeghboyugsatii.jpg
/a/airplane_cabin/sun_blczihbhbntqccux.jpg
/a/airplane_cabin/sun_ayzaayjpoknjvpds.jpg
/a/airplane_cabin/sun_afuoinkozbbhqksk.jpg
/b/butte/sun_asfnwmuzhtjrztns.jpg
/b/butte/sun_ajzkngginlffsozz.jpg
/b/butte/sun_adonkmfgywrhpakt.jpg
/c/cabin/outdoor/sun_atqvmarllxqynnks.jpg
/c/cabin/outdoor/sun_acfcobswmnoyhyfi.jpg
/c/cabin/outdoor/sun_afgjdqosvakljsmc.jpg
I want to create dictionary with "a","b","c" or any letter, as a key (I cant hard code it) with dictionary as a value that contains place where images were taken and list of images.
But when I want to read my saved data I'm getting None as a value
print(data["a"])
Output: {'auto_factory': None}
Try to use defaultdict from python stdlib. It's very convenient in situations like this:
from collections import defaultdict
data = defaultdict(lambda: defaultdict(list))
with open("Training_01.txt", "r") as open_file:
text = open_file.read()
text = text.split("\n")
for line in text:
try:
_, key, subkey, rem = line.split("/", 3)
data[key][subkey].append(rem)
except:
print("Can't")
print(data)
Explanation: the first time you access data (which is a dictionary) with a not existing key, a new entry for such a key will be created. This entry is going to be again a defaultdict, but the first try you access it with a not existing key, again a new (nested this time) entry will be created. And this entry will be a list. So, then you can safely append a new element to such a list.
UPD: Here is a way to implement the same requirement but without defaultdict:
data = {} # just a plain dict
# for ...:
data[key] = data.get(key, {}) # try to access the key, if it doesn't exist - create a new dict entry for such a key
data[key][subkey] = data[key].get(subkey, []) # same as above but for the sub key
data[key][subkey].append(rem) # finally do the job
Because data[i[1]] = {i[2]:[].append(i[3])} create a new 2nd layer dictionary everytime.
This is a possible solution. It is the cleanest solution, but it shows step by step. It creates a new dict and list if the key is not in the last layer dict. But it append value to the list if the dict has the key.
data = {"":{"":[]}}
with open("Training_01.txt", "r") as open_file:
text = open_file.read()
text = text.split("\n")
for i in text:
i = i.split("/")
key_1 = i[1]
key_2 = i[2]
value = i[3]
try:
if key_1 in data.keys(): # Whether the key i[1] is in the 1st layer of the Dict
if key_2 in data[key_1].keys(): # Whether the key i[2] is in the 2nd layer of the Dict
# Yes, Append to the list
data[key_1][key_2].append(value)
else:
# No, Creat a new list
data[key_1][key_2] = [value]
# if i[1] not in the 1st layer, creat a 2nd layer dict with i[2] as key, i[3] as value
else:
data[key_1] = {key_2:[value]}
except:
print("Can't")
print(data['a'])

RAKE split sentences function on a Python dictionary

How would I be able to apply this function to just the values within a python dictionary:
def split_sentences(text):
"""
Utility function to return a list of sentences.
#param text The text that must be split in to sentences.
"""
sentence_delimiters = re.compile(u'[\\[\\]\n.!?,;:\t\\-\\"\\(\\)\\\'\u2019\u2013]')
sentences = (sentence_delimiters.split(text))
return sentences
The code I have used to create the dictionary from a CSV file input:
with open('second_table.csv', mode='r') as infile:
#Read in the csv file
reader = csv.reader(infile)
#Skip the headers
next(reader, None)
#Iterates through each row to get the key value pairs
mydict = {rows[0]:rows[1] for rows in reader}
The python dictionary looks like so:
{'INC000007581947': '$BREM - CATIAV5 - Catia does not start',
'INC000007581991': '$SPAI - REACT - react',
'INC000007582037': 'access request',
'INC000007582095': '$HAMB - DVOBROWSER - ACCESS RIGHTS',
'INC000007582136': 'SIGLUM issue by opening a REACT request'}
mydict.values() gives you all the values in the dictionary. You can then iterate over them and use your function.
for value in mydict.values():
split_sentences(value)
There are different solutions, depending on if you want to create a new dictionary or simply update the one you already have.
To update the dictionary values:
mydict.update({k : split_sentences(v) for k, v in mydict.items()})
To create a new dictionary:
new_dict = {k : split_sentences(v) for k, v in mydict.items()}

Python: dictionary to collection

I have a file with 2 columns:
Anzegem Anzegem
Gijzelbrechtegem Anzegem
Ingooigem Anzegem
Aalst Sint-Truiden
Aalter Aalter
The first column is a town and the second column is the district of that town.
I made a dictionary of that file like this:
def readTowns(text):
input = open(text, 'r')
file = input.readlines()
dict = {}
verzameling = set()
for line in file:
tmp = line.split()
dict[tmp[0]] = tmp[1]
return dict
If I set a variable 'writeTowns' equal to readTowns(text) and do writeTown['Anzegem'], I want to get a collection of {'Anzegem', 'Gijzelbrechtegem', 'Ingooigem'}.
Does anybody know how to do this?
I think you can just create another function that can create appropriate data structure for what you need. Because, at the end you will end up writing code which basically manipulates the dictionary returned by readTowns to generate data as per your requirement. Why not keep the code clean and create another function for that. You Just create a name to list dictionary and you are all set.
def writeTowns(text):
input = open(text, 'r')
file = input.readlines()
dict = {}
for line in file:
tmp = line.split()
dict[tmp[1]] = dict.get(tmp[1]) or []
dict.get(tmp[1]).append(tmp[0])
return dict
writeTown = writeTowns('file.txt')
print writeTown['Anzegem']
And if you are concerned about reading the same file twice, you can do something like this as well,
def readTowns(text):
input = open(text, 'r')
file = input.readlines()
dict2town = {}
town2dict = {}
for line in file:
tmp = line.split()
dict2town[tmp[0]] = tmp[1]
town2dict[tmp[1]] = town2dict.get(tmp[1]) or []
town2dict.get(tmp[1]).append(tmp[0])
return dict2town, town2dict
dict2town, town2dict = readTowns('file.txt')
print town2dict['Anzegem']
You could do something like this, although, please have a look at #ubadub's answer, there are better ways to organise your data.
[town for town, region in dic.items() if region == 'Anzegem']
It sounds like you want to make a dictionary where the keys are the districts and the values are a list of towns.
A basic way to do this is:
def readTowns(text):
with open(text, 'r') as f:
file = input.readlines()
my_dict = {}
for line in file:
tmp = line.split()
if tmp[1] in dict:
my_dict[tmp[1]].append(tmp[0])
else:
my_dict[tmp[1]] = [tmp[0]]
return dict
The if/else blocks can also be achieved using python's defaultdict subclass (docs here) but I've used the if/else statements here for readability.
Also some other points: the variables dict and file are python types so it is bad practice to overwrite these with your own local variable (notice I've changed dict to my_dict in the code above.
If you build your dictionary as {town: district}, so the town is the key and the district is the value, you can't do this easily*, because a dictionary is not meant to be used in that way. Dictionaries allow you to easily find the values associated with a given key. So if you want to find all the towns in a district, you are better of building your dictionary as:
{district: [list_of_towns]}
So for example the district Anzegem would appear as {'Anzegem': ['Anzegem', 'Gijzelbrechtegem', 'Ingooigem']}
And of course the value is your collection.
*you could probably do it by iterating through the entire dict and checking where your matches occur, but this isn't very efficient.

how to use string as list's indices in Python

for line in f.readlines():
(addr, vlanid, videoid, reqs, area) = line.split()
if vlanid not in dict:
dict[vlanid] = []
video_dict = dict[vlanid]
if videoid not in video_dict:
video_dict[videoid] = []
video_dict[videoid].append((addr, vlanid, videoid, reqs, area))
Here is my code, I want to use videoid as indices to creat a list. the real data of videoid are different strings like this : FYFSYJDHSJ
I got this error message:
video_dict[videoid] = []
TypeError: list indices must be integers, not str
But now how to add identifier like 1,2,3,4 for different strings in this case?
Use a dictionary instead of a list:
if vlanid not in dict:
dict[vlanid] = {}
P.S. I recommend that you call dict something else so that it doesn't shadow the built-in dict.
Don't use dict as a variable name. Try this (d instead of dict):
d = {}
for line in f.readlines():
(addr, vlanid, videoid, reqs, area) = line.split()
video_dict = d.setdefault(vlanid, {})
video_dict.setdefault(videoid, []).append((addr, vlanid, videoid, reqs, area))
As suggested above, creating dictionaries would be the most ideal code to implement. (Although you should avoid calling them dict, as that means something important to Python.
Your code may look something like what #aix had already posted above:
for line in f.readlines():
d = dict(zip(("addr", "vlanid", "videoid", "reqs", "area"), tuple(line.split())))
You would be able to do something with the dictionary d later in your code. Just remember - iterating through this dictionary will mean that, if you don't use d until after the loop is complete, you'll only get the last values from the file.

Categories

Resources