Python: Adding significant values to existing values in a dictionary - python

I want to write a python script that is extracting certain conditions which is as follows:
a a1 1
2
3
a2 0
1
b b1 1
2
b2 0
3
Until now what I was able to do is create a dictionary of first 2 columns and then create another dictionary for the 2nd and 3rd column. But I want all the 3 columns in one dictionary.
Here is the pseudo code that I have written so far:
mydict = {}
for lines in f:
if 'a' or 'b' in lines:
key = a
if 'a1' in lines:
value = a1
mydict.setdefault(key, []).append(value)
and something similar for the second dictionary as well.
Please help me out !
expected output:
{ 'a' : [ 'a1': [1,2,3]],'b':['b1': [0,1]}
As I mentioned earlier, I want to create this dictionary from 2 existent dictionaries which look something like this
{'a': a1, 'b':b1} #First Dictionary
{'a1': [1,2,3], 'b1': 123} #Second Dictionary
I created these 2 dictionaries from a text file. And the code that is posted, is the code of how I extracted these 2 dictionaries.

not the sexiest code on earth i admit
mydict = {}
for line in data.split('\n'):
if not line:
continue
line = line.split()
if len(line) == 3:
l1_key = line.pop(0)
mydict[l1_key] = {}
if len(line) == 2:
l2_key = line.pop(0)
mydict[l1_key][l2_key] = []
mydict[l1_key][l2_key].append(line.pop(0))
print(mydict)

Related

Create dictionary out of txt file. One alphabet letter per row. Key is letter and value should be iteration of the loop

i got a problem..
I have a txt file that looks like this:
a
b
c
d
One letter per row, there is not two values per row, so nothing to split..
This code works, if I add a second value in my alphabetFile.
dict = {}
with open("alphabet.txt") as alphabetFile:
for line in alphabetFile:
(key, val) = line.split()
dict[int(key)] = val
print(dict)
But I should only have 1 value per row... Im thinking the iteration should be the second value.. but im stuck and tired.. any ideas?
You can use enumerate() to iterate over lines. Also, don't use dict as name of variable (it shadows Python built-in):
dct = {}
with open("alphabet.txt") as alphabetFile:
for iteration, line in enumerate(alphabetFile, 1):
dct[line.strip()] = iteration
print(dct)
Prints:
{'a': 1, 'b': 2, 'c': 3, 'd': 4}

appending dictionary inside a dictionary [duplicate]

This question already has an answer here:
Nested dictionary from nested list
(1 answer)
Closed 4 years ago.
file2.txt file1.txt I have an initial dictionary like:
{'A':'B'}
I have two text file like:
file1.txt
B[
C1:
C2:
file2.txt
C1[
b1:
b2:
C2[
n1:
n2:
what i am trying is to do that i take string ending with '[' as key and string ending with ':' as value
file_directory = ['Desktop/input_file/file1.txt','Desktop/input_file/file2.txt']
now I am iterating through the list of a directory which contains some text file, and take the value of initial dictionary that is B and searching in each directory if I found the B I make it as key and taking all as value except B and the new dictionary will be like this:
{'A':{'B':{'C1','C2'}}}
and again iterate through the all director and searching for each value of key B if it is found again make it key and append its value and then the new dictionary will be like:
{'A':{'B':{'C1':{'b1',b2'},'C2':{'n1','n2'}}}}
and it goes in a similar way until we don't get any match for any value and if any value is not found in any directory ,take value as key and put its value as empty braces like I search for the value b1,b2,n1 and n2 and did not found it will look like:
{'A':{'B':{'C1':{'b1':{},'b2':{}},'C2':{'n1':{},'n2':{}}}}}
Your explanation does not really make sense; But if I have understood your question properly you mean the following:
# dict 'd' with one key, that has a value 'b'
d={'a': 'b'}
# dict c one key with value 2
c={'f': 2}
# appending c into d/ by creating a key 'b' that has dict c as a value
d['b']=c
#output
{'a': 'b', 'b': {'f': 2}}
# let's update the dictionary b in d by adding another key j in b
d['b']['j']= 'r'
# output
{'a': 'b', 'b': {'f': 2, 'j': 'r'}}

Modifying a dictionary contained within a list

I am currently writing some code that reads lines in from a text file. The line is split into 3 different segments, with the first segment being a user ID.
For example, one line would look like this:
11 490 5
I have a list with as many elements as there are users, where each element corresponds with a user (eg exampleList[4] stores data for the 5th user).
Each list element contains a dictionary of indefinite length, where the key is the second segment of the line, and the value is the third segment of the line.
The length of the dictionary (the number of key-value pairs) increases if the same user's ID occurs in another line. The idea is that when another line with the same user ID is encountered, the data from that line is appended to the dictionary in the list element that corresponds to that user.
For example, the above line would be stored in something like this:
exampleList[10] = {490:5}
and if the program read another line like this: 11 23 9
the list item would update itself to this:
exampleList[10] = {490:5, 23:9}
The way my program works is that it first collects the number of users, and then creates a list like this:
exampleList = [{}] * numberOfUsers
It then extracts the position of whitespace in the line using re.finditer, which is then used to extract the numbers through basic string operations.
That part works perfectly, but I'm unsure of how to update dictionaries within a list, namely appending new key-value pairs to the dictionary.
I've read about using a for loop here, but that won't work for me since that adds it to every dictionary in the cell instead of just appending it to the dictionary in a certain cell only.
Sample code:
oFile = open("file.txt", encoding = "ISO-8859-1")
text = oFile.readlines()
cL = [{}] * numOfUsers #imported from another method
for line in text:
a = [m.start() for m in re.finditer('\t', line)]
userID = int(line[0:a[0]])
uIDIndex = userID - 1
cL[uIDIndex].update({int(line[a[0]+1:a[1]]):int(line[a[1]+1:a[2]])})
print(cL)
file.txt:
1 242 3
3 302 3
5 333 10
1 666 9
expected output:
[{242:3 , 666:9},{},{302:3},{},{333:10}]
actual output:
[{242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}, {242: 3, 333: 10, 302: 3, 666: 9}]
For some reason, it populates all dictionaries in the list with all the values.
I'm not positive I understand your problem correctly but I was able to get the output you desired.
Note that this solution completely ignores the fourth value in the list
import re
fileData = [] #data from file.txt parsed through regex
with open("file.txt") as f:
for line in f:
regExp = re.match(r"(\d+)\s+(\d+)\s(\d+)", line) #extracts data from row in file
fileData.append((int(regExp.group(1)), int(regExp.group(2)), int(regExp.group(3)))) #make 2-d list of data
maxIndex = max(fileData, key=lambda x: x[0])[0] #biggest index in the list (5 in this case)
finaList = [] #the list where your output will be stored
for i in range(1, maxIndex+1): #you example output showed a 1-indexed dict
thisDict = {} #start with empty dict
for item in fileData:
if item[0] == i:
thisDict[item[1]] = item[2] #for every item with same index as this dict, add new key-value to dict
finaList.append(thisDict) #add this dict to output list
print(finaList)
You can just access the dictionary by the index. Here is a simple example:
>>> A = []
>>> A.append(dict())
>>> A.append(dict())
>>> A[0][5] = 7
>>> A
[{5: 7}, {}]
>>> A[1][4] = 8
>>> A[0][3] = 9
>>> A[1][8] = 10
>>> A
[{3: 9, 5: 7}, {8: 10, 4: 8}]

Adding multiple dictionaries to a key in python dictionary

I am trying to add multiple dictionaries to a key.
e.g.
value = { column1 : {entry1 : val1}
{entry2 : val2}
column2 : {entry3 : val3}
{entry4 : val4}
}
What exactly I am trying to do with this code is:
There is a file.txt which has columns and valid entries for that header. I am trying to make a dictionary with columns as key and for each column another dictionary for each valid entry.
So I am parsing the text file line by line to find the pattern for column and entries and storing it in a variable, check if the column(which is a key) already exists in the dictionary, if exists then add another dictionary to the column, if not create a new entry. I Hope this makes sense.
Sample contents of file.txt
blah blah Column1 blah blah
entry1 val1
entry2 val2
blah blah Column2 blah blah
entry3 val3
entry4 val4
My code:
from __future__ import unicode_literals
import os, re, string, gzip, fnmatch, io
from array import *
header = re.compile(...) #some regex
valid_entries = re.compile(---) #some regex
matches=[]
entries=[]
value = {'MONTH OF INTERVIEW' : {'01': 'MIN VALUE'}}
counter = 0
name = ''
f =open(r'C:/file.txt')
def exists(data, name):
for key in data.keys():
if key == name :
print "existing key : " + name
return True
else :
return False
for line in f:
col = ''
ent = ''
line = re.sub(ur'\u2013', '-', line)
line = re.sub(ur'\u2026', '_', line)
m = header.match(line)
v = valid_entries.match(line)
if m:
name= ''
matches.append(m.groups())
_,_, name,_,_= m.groups()
#print "name : " + name
if v:
entries.append(v.groups())
ent,col= v.groups()
#print v.groups()
#print "col :" + col
#print "ent :" + ent
if (name is not None) and (ent is not None) and (col is not None):
print value
if exists(value, name):
print 'inside existing loop'
value[name].update({ent:col})
else:
value.update({name:{ent:col}})
print value
problem with this code is , it is replacing the values of the sub dictionary and also it is not adding all the values to the dictionary.
I am new to python, so this could be a naive approach to handle this kind of situation. If you think there is a better way of getting what I want, I would really appreciate if you tell me.
Dictionaries have only one value per key. The trick is to make that value a container too, like a list:
value = {
'column1': [{entry1 : val1}, {entry2 : val2}]
'column2': [{entry3 : val3}, {entry4 : val4}]
}
Use dict.setdefault() to insert a list value when there is no value yet:
if name is not None and ent is not None and col is not None:
value.setdefault(name, []).append({ent: col})
You could just make the values one dictionary with multiple (ent, col) key-value pairs here:
if name is not None and ent is not None and col is not None:
value.setdefault(name, {})[ent] = col
Your exists() function was overcomplicating a task dictionaries excel at; testing for a key is done using in instead:
if name in value:
would have sufficed.
I would keep the keys as a list of dictionaries, so you can extend or append
>>> d = {}
>>> d[1] = [{'a': 1}]
>>> d[1].append({'b':2})
>>> d
{1: [{'a': 1}, {'b': 2}]}
You can use defaultdict and regex for this (demo here):
with open('/path/to/file.txt', 'rU') as f: # read the contents from the file
lines = f.readlines()
import re
from collections import defaultdict
d = defaultdict(list) # dict with default value: []
lastKey = None
for line in lines:
m = re.search('Column\d',line) # search the current line for a key
if m: lastKey = m.group()
else:
m = re.search('(?<=entry\d ).*',line) # search the current line for a value
if m: d[lastKey].append(m.group()) # append the value
Output:
[('Column1', ['val1', 'val2']), ('Column2', ['val3', 'val4'])]
Note: Of course, the above code assumes your file.txt was formatted as in your example. For your real file.txt data you might have to adjust the regex.

Dictionary with named values?

I have a file like this :
A X V1
A Y V2
B X V3
B Y V4
Let's say the first column is a model type, second column is a version number and third is the value of something related.
I would like to answer the question : "What is the value of model A, version X ?"
For all values and all versions.
I wanted to use a dict but i only know dicts with one value for each keys. This one here needs two keys, ie something like :
d[model][version] = value
How would you do this ?
You can nest dictionaries:
d['A'] = {}
d['A']['X'] = 'V1'
or you can use tuple keys instead:
d[('A', 'X')] = 'V1'
Nesting would make it easier to list all known versions for a given model:
versions_for_model = d['A'].keys()
Creating a nested dictionary setup can be simplified a little by using collections.defaultdict():
d = defaultdict(dict)
d['A']['X'] = 'V1'
Here trying to access d['A'] automatically creates a new dictionary value.
with open("Input.txt") as inputFile:
lines = [line.strip().split() for line in inputFile]
result = {}
for k1, k2, v in lines:
result.setdefault(k1, {})[k2] = v
print result
Output
{'A': {'Y': 'V2', 'X': 'V1'}, 'B': {'Y': 'V4', 'X': 'V3'}}
You can access the individual elements like this
print result["A"]["Y"]
Output
V2

Categories

Resources