Reset List When Condition Met - python

I'm trying to make a function that reads through a protocol buffer and creates a dictionary with a list matched up to each key, like so:
Source:
{
name: "foo"
...
some_value: "a"
some_value: "b"
},
{
name: "bar"
...
some_value: "c"
some_value: "d"
}
Desired Output:
{'foo': ['a','b'], 'bar': ['c','d',]}
Here is my code:
import re
STATIC_SRC = '/path/to/my/file.txt'
def CountBrackets(line):
if '{' in line:
return 1
if '}' in line:
return -1
else:
return 0
with open(STATIC_SRC, 'r') as src_file:
bracket_count = 0
key = ''
values = []
my_dict = {}
for line in src_file:
line = line.strip()
bracket_count += CountBrackets(line)
# Finds line like 'name: "foo"' and stores 'foo' as key
if line.startswith('name:'):
key = re.findall('"([^"]*)"', line)
key = ''.join(key)
# Finds line like 'some_value: "a"' and adds 'a' to list
if line.startswith('some_value:'):
value = re.findall('"([^"]*)"', line)
values.append(value)
# When bracket count returns to 0, it's reached the end of a tupe
# and should store the current key and list.
if bracket_count == 0:
my_dict[key] = values
del values[:] # This is where I'm having issues.
print(role_dict)
My problem is that I can't get the list to successfully clear at the end of the tuple (in the source file). I have tried the following two methods, neither gave the correct output.
Method:
values = []
Result:
{'foo': ['a', 'b'], 'bar': ['a','b','c','d']}
Method:
del values[:]
Result:
{'foo': [], 'bar': []}
I've had it print all the keys/values as it loops and those are working as desired. It's also writing to the dictionary at the write time based on bracket count. It seems that the method I used for clearing somehow clears 'values' even after they've been added to the dictionary.
Can anyone shed some light on what's going wrong here and how to properly empty the list of values? Thanks!
EDIT: By request, tl;dr
I'd like the program to loop through this logic:
if x:
- store something to 'key'
if y:
- add something to a list 'values'
if z:
- write the current 'key' and 'values' to a dictionary
- clear the list 'values'
How do I clear the list of values at the end?

I don't know why you are getting that output on your first attempt. It worked for me. See below.
with open(STATIC_SRC, 'r') as src_file:
bracket_count = 0
key = ''
values = []
my_dict = {}
for line in src_file:
print(values)
line = line.strip()
bracket_count += CountBrackets(line)
# Finds line like 'name: "foo"' and stores 'foo' as key
if line.startswith('name:'):
key = re.findall('"([^"]*)"', line)
key = ''.join(key)
# Finds line like 'some_value: "a"' and adds 'a' to list
if line.startswith('some_value:'):
value = re.findall('"([^"]*)"', line)
values.extend(value) # append create a new list inside the existing list
# When bracket count returns to 0, it's reached the end of a tupe
# and should store the current key and list.
if bracket_count == 0:
my_dict[key] = values
values = []
print(my_dict) # the name of the dict was wrong
The result is
{'foo': ['a', 'b'], 'bar': ['c', 'd']}
I just edited the last print and replaced append with extend.
You cannot del values because that will delete the value in the dict, as it is the same object in memory.
d = {}
k = [1,2,3]
d['a'] = k
d
# {'a': [1, 2, 3]}
id(d['a']) == id(k)
# True
Running Python 2.7.6.

Related

How would I detect insertion of the same key with a different value into a dict?

So my goal for this problem is to, given 2 strings, str1 and str2, create a dictionary such that the characters in str1 are the keys and the corresponding characters in str2 are the values.
ie. crackthecode('apple','byytr') returns
{'a':'b','p':'y','l':'t','e':'r'}
and if it is inconsistent, ie. crackthecode('apple','byptr') then returns
{}, an empty dictionary.
This is my code, I'm just not sure how to do the inconsistent case.
PS. I cannot use zip for this question.
Below is my code.
def crackthecode(str1, str2):
final = {}
x = 0
for i in list(str1):
final[i]=str2[x]
x = x + 1
return final
All help is appreciated, thanks!
You can check if the key is already present in the dictionary, and compare the value with the new character. If they are not equal, return an empty dictionary. Otherwise, add the key-value pair to the dictionary.
You can use this code which uses the EAFP principle.
>>> def crackthecode(str1, str2):
final = {}
for i, key in enumerate(str1):
try:
if final[key] != str2[i]:
return {}
except KeyError:
final[key] = str2[i]
return final
>>> crackthecode('apple','byytr')
{'a': 'b', 'p': 'y', 'l': 't', 'e': 'r'}
>>> crackthecode('apple','byptr')
{}
Edit: Same code without using enumerate (requested by OP)
def crackthecode(str1, str2):
final = {}
for i in range(len(str1)):
try:
if final[str1[i]] != str2[i]:
return {}
except KeyError:
final[str1[i]] = str2[i]
return final

facing problem while appending dictionaries of list

for li in list2:
tid=li
for i,li2 in enumerate(list):
s2=li2
if (s2.find(tid)>0 ):
i+=1
s3=list[i]
y=s3.find('RUNNABLE')
if( y>0 ) :
dict={tid:[].append('RUNNABLE')
I am trying to append a dictionary and the list .
The outer loop will fetch element from the list which will ultimately be the key and the inner loop will append the list .
but the output is {'tid=value': None}
Your code is a bit confusing, would that be the proposal?
list_keys = ['a', 'b', 'c']
list_values = ['not RUNNABLE', 'not RUNNABLE', 'c RUNNABLE']
list_dict = []
for key in list_keys:
for index, value in enumerate(list_values):
if key in value:
if 'RUNNABLE' in value:
list_dict.append({key: ['RUNNABLE']})
print(list_dict)
The issue is in dict={tid:[].append('RUNNABLE'). Try this:
print([].append('RUNNABLE'))
The return value of append is None. What you wanted to do is probably this:
a = {}
a.setdefault('foo', []).append('RUNNABLE')
print(a) # {'foo': ['RUNNABLE']}
a.setdefault('foo', []).append('RUNNABLE')
print(a) # {'foo': ['RUNNABLE', 'RUNNABLE']}
The method setdefault inserts the second argument under the key if it is absent and returns it. Otherwise it just returns it. A single use of it like this is:
if 'foo' not in a:
a['foo'] = []
a['foo'].append('RUNNABLE')
Another solution for your problem is defaultdict, but it's a little overkill for a simple case like that.

iterate over a subset of dictionary keys

I am looking to learn how to pass certain keys/values in a dictionary to another function within a for loop. The "certain" keys all share the same initial string and are incremented by a trailing integer like this:
data = {}
data["HMD1"] = [a,b,c]
data["HMD2"] = [d,f,g] #and so on...
There are other keys with dissimilar names witin the same dictionary. Now within a for loop I would like to pass the values for each key that starts with "HMD" to another function. Here is a minimal working example of a failed attempt:
data = {}
data["HMD1"] = [0,2,3]
data["HMD2"] = [5,6,4]
data["not"] = 1237659398
data["HMD3"] = [1,1,1]
def dummyfun(vargin):
print(vargin)
return vargin
for f in range(1,2,1):
out = dummyfun(data[eval(''.join(("HMD",str(f))))])
This was a poor guess, of course it returns an error because eval() tries to evaluate "HMD1" which is not a variable but a key in data. Does anyone know how to do this properly?
You don't need eval at all for this. You only need to build the string with .format for example
for f in range(1,4): #range don't include the end point
out = dummyfun(data["HMD{}".format(f)])
with this you get the desire result. But that will fail if the key is not in the dict, you can check it first, catch the exception or provide a default value in case the desire key is not there
#check first
for f in range(1,4):
key = "HMD{}".format(f)
if key in data:
out = dummyfun(data[key])
#catch the exception
for f in range(1,4):
try:
out = dummyfun(data["HMD{}".format(f)])
except KeyError:
print("key",f,"is not in the data")
#provide a default value
for f in range(1,4):
out = dummyfun(data.get("HMD{}".format(f),None))
Just iterate through the dictionary using a for loop and use an if statement to check for validity of the keys:
for key in yourDict: #a for loop for dict iterates through its keys
if 'HMD' in key: #or you can replace with any other conditional
#DO WHAT YOU WANT TO DO HERE
And here's a quick working example:
>>> data = {'HMD1': [1,2,3], 'HMD23':'heyo mayo', 'HMNOT2':'if this prints, I did something wrong'}
>>> for key in data:
... if 'HMD' in key:
... print data[key]
...
[1, 2, 3]
heyo mayo
With further understand of what you want, you can also look at this backwards and create key strings and print the values that those key's point to:
#let's say you want to print HMD1, HMD2, HMD4, but not anything else
keylist = [#list of keys that you want]
for key in keylist:
if key in data:
print data[key]
and, again, a working example.
>>> data = {'HMD1': [1,2,3], 'HMD3':'heyo mayo, this shouldnt print', 'HMD4':123, 'HMD2':['g', 'h', 'i'], 'HMNOT2':'if this prints, I did something wrong'}
>>> keylist = ['HMD1', 'HMD2', 'HMD4']
>>> for key in keylist:
... if key in data:
... print data[key]
...
[1, 2, 3]
['g', 'h', 'i']
123

How to add list object to Dictionary in Python

I am trying to add list object to Dictionary.
Code:
for line in file:
splitObj=line.split("=") #split a line xxx= yyy using = delimiter
listObj=list(splitObj)
chip_mem.update(listObj[0], listObj[1])
This didn't help. Can anyone please let me know how to add the contents of the list to the dict as a key, value pair?
for line in file:
pieces = line.split("=")
chip_mem[pieces[0]] = pieces[1]
Note that there's no reason to call list() on the result of .split, since it's already a list.
Note that if not all of your lines have = signs in them, you might need to check for this:
for line in file:
pieces = line.split("=")
if len(pieces) > 1:
chip_mem[pieces[0]] = pieces[1]
Assuming you get a key and a value made for each thing in your list by splitting them on the equal sign, you can always do:
for k,v in list.split("="):
mydict[k] = v
dict update method requires other key-value pairs, see:
>>> mydict = {}
>>> mydict.update({'param': 'value'})
>>> print mydict # prints{'param': 'value'}
So in your case, for instance:
myfile = open("config.txt")
lines = myfile.readlines()
chip_mem = {}
for line in lines:
parts = line.strip().split("=")
chip_mem.update({parts[0]: parts[1]})
print chip_mem

Replace dict key by value of other dict

Today I need to replace the key of dict one by value of dict two. Dict one has multiple keys and I only want to replace the keys which match dict 2.
In the end I want to get the dict one back with the old keys (the ones which did not match) and the new keys (which have been changed when they matched)
I wrote the following script but I get no output so I am not sure if I am doing it right, can someone explain to me?
Thanks a lot
ERCC = {}
my_file = open('a.txt')
for line in my_file:
config,name = line.strip().split()
ERCC[contig] = name
RSEM = {}
names_file = open('b.txt')
for line in names_file:
genes, count = line.strip().split()
RSEM[gene] = count
def convert(RSEM,ERCC):
for key, value in RSEM.items():
for keys, values in ERCC.items():
if keys == key:
RSEM[key] = values
return RSEM
print RSEM
convert(RSEM, ERCC)
>>> dic={}
>>> for k,v in myboi.items():
r=input("Enter item to Update write in ""=")
if r:
dic[r]=v
else:
dic[k]=v
Enter item to Update write in ="Mahesh"
Enter item to Update write in ="Saka"
>>>
>>> dic
{'Mahesh': 'Mahesh', 'Saka': 'Mahesh'}
You want compulsary input key in this program you want update one or more time you empty dic={}
result={'Mahesh': 'Mahesh', 'Saka': 'Mahesh'}
>>> fi.close()
>>> fi=open("m.txt","r")
>>> fi.readlines()
['Maheshname']
>>> fi=open("m.txt","w+")
>>> for k,v in myboi.items():
fi.write("'"+k+"'"+":"+"'"+v+"'")
>>> fi.close()
>>> fi=open("m.txt","r")
>>> fi.readlines()
["'Mahesh':'Mahesh''name':'Mahesh'"]
Here's a two-liner for the convert function:
RSEM = {key: ERCC.get(key, RSEM[key]) for key in RSEM}
print RSEM
To dump a dict to a file just do:
with open("your_file_name", "w") as dumpfile:
dumpfile.write(str(RSEM))
Your code seems to be fine. But you have used return statement before print statement. The execution of convert function stops at return *** and the print statement is not executed at all. That is the reason why you are not getting any output.

Categories