simple code for modifying nested list in dict - python

I am using a dict in python which has the following content, basiclly it has a nested list in value set, now I want to modify the nested list.
insn = { "pop":[1,["operand1 = [esp]", "esp = esp + 4"]]}
Here is what I am doing
for k,v in insn.items():
for i, s in enumerate(v):
v[1][i] = s.replace("old", "new")
insn.update({k:v})
The code is pretty messed, I wonder if there is a simple way to do this ?

I am not entirely sure what you are trying to do here. But supposing you want to change esp or some other string within the embedded list you can do something like this:
for k, v in insn.items():
for i in range(len(v[1])):
v[1][i] = v[1][i].replace('esp', 'new_esp')
insn.update({k:v})
now you get:
>>> insn
{'pop': [1, ['operand1 = [new_esp]', 'new_esp = new_esp + 4']]}

Related

Convert a dictionary to accessible array in Python

How can I convert the following dictionary which contains an array within an array: to an array easily so I can access for example array[0]
{'New Beton': [`'C:\\User\\New map\\Test1.jpg',`'C:\\User\\New map\\Test2.jpg', 'C:\\User\\New map\\Test3.jpg']}
Which I need to convert to
New Beton = ["C:\\User\\New map\\Test1.jpg", "C:\\User\\New map\\Test2.jpg", "C:\\User\\New map\\Test3.jpg"]
Just access it directly.
you_dict['New Beton'][0]
And make sure your variable names don't have whitespace. I think except 'Rockstar' no language allows that.
Do you want to convert dictionary into a nested list? Then, something like this will work.
def convert(d):
l = []
for k, v in d.items():
l.append(v)
return l
d = {'foo':['bar', 'baz']}
l = convert(d)
print(l[0])
but there are better ways to get that value without creating a list. it'd ve great if you could share more details about what you want to do so that i can give you specific examples.

How to reset value of multiple dictionaries elegantly in python

I am working on a code which pulls data from database and based on the different type of tables , store the data in dictionary for further usage.
This code handles around 20-30 different table so there are 20-30 dictionaries and few lists which I have defined as class variables for further usage in code.
for example.
class ImplVars(object):
#dictionary capturing data from Asset-Feed table
general_feed_dict = {}
ports_feed_dict = {}
vulns_feed_dict = {}
app_list = []
...
I want to clear these dictionaries before I add data in it.
Easiest or common way is to use clear() function but this code is repeatable as I will have to write for each dict.
Another option I am exploring is with using dir() function but its returning variable names as string.
Is there any elegant method which will allow me to fetch all these class variables and clear them ?
You can use introspection as you suggest:
for d in filter(dict.__instancecheck__, ImplVars.__dict__.values()):
d.clear()
Or less cryptic, covering lists and dicts:
for obj in ImplVars.__dict__.values():
if isinstance(obj, (list, dict)):
obj.clear()
But I would recommend you choose a bit of a different data structure so you can be more explicit:
class ImplVars(object):
data_dicts = {
"general_feed_dict": {},
"ports_feed_dict": {},
"vulns_feed_dict": {},
}
Now you can explicitly loop over ImplVars.data_dicts.values and still have other class variables that you may not want to clear.
code:
a_dict = {1:2}
b_dict = {2:4}
c_list = [3,6]
vars_copy = vars().copy()
for variable, value in vars_copy.items():
if variable.endswith("_dict"):
vars()[variable] = {}
elif variable.endswith("_list"):
vars()[variable] = []
print(a_dict)
print(b_dict)
print(c_list)
result:
{}
{}
[]
Maybe one of the easier kinds of implementation would be to create a list of dictionaries and lists you want to clear and later make the loop clear them all.
d = [general_feed_dict, ports_feed_dict, vulns_feed_dict, app_list]
for element in d:
element.clear()
You could also use list comprehension for that.

Python create nested dictionary from list with nested tuples

Thank you for your help. Still very new to python. I trust I'm not abusing the goodwill of SO with such questions. I am trying to evolve from SQL database mentality to a python lists/dictionary approach.
Here is a snippet of a list with nested tuples (always containing three elements):
List = [(u'32021', u'161', 1696.2), (u'32021', u'162', 452.2), (u'32044', u'148', 599.2), (u'32044', u'149', 212.2)]
Can this be converted to a dictionary with nested dictionaries, something like this:
{'32021': ('161': 1696.2, '162': 452.2), '32044': ('148': 599.2, '149': 212.2)}
I addressed a similar problem that only had two items in each tuple using:
d = defaultdict(list)
for k, v in values:
d[k].append(v)
For three items, is one solution using indexing with a for loop?
Thank you.
You probably want this:
d = {}
for k1,k2,v in List:
d[(k1,k2)] = v
or even this:
d = {(k1,k2):v for k1,k2,v in List}
you can do this case with a nested defaultdict:
d = defaultdict(lambda:defaultdict(list))
for k1, k2, v in values:
d[k1][k2].append(v)
print d['32044']['148']
[599.2]
etc.
Also, see the bunch pattern, which is an easy-to-use similar idea that even lets you assign attributes inline without having to declare them first:
https://pypi.python.org/pypi/bunch/1.0.1

Python - Updating value in one dictionary is updating value in all dictionaries

I have a list of dictionaries called lod. All dictionaries have the same keys but different values. I am trying to update one specific value in the list of values for the same key in all the dictionaries.
I am attempting to do it with the following for loop:
for i in range(len(lod)):
a=lod[i][key][:]
a[p]=a[p]+lov[i]
lod[i][key]=a
What's happening is each is each dictionary is getting updated len(lod) times so lod[0][key][p] is supposed to have lov[0] added to it but instead it is getting lov[0]+lov[1]+.... added to it.
What am I doing wrong?
Here is how I declared the list of dicts:
lod = [{} for _ in range(len(dataul))]
for j in range(len(dataul)):
for i in datakl:
rrdict[str.split(i,',')[0]]=list(str.split(i,',')[1:len(str.split(i,','))])
lod[j]=rrdict
The problem is in how you created the list of dictionaries. You probably did something like this:
list_of_dicts = [{}] * 20
That's actually the same dict 20 times. Try doing something like this:
list_of_dicts = [{} for _ in range(20)]
Without seeing how you actually created it, this is only an example solution to an example problem.
To know for sure, print this:
[id(x) for x in list_of_dicts]
If you defined it in the * 20 method, the id is the same for each dict. In the list comprehension method, the id is unique.
This it where the trouble starts: lod[j] = rrdict. lod itself is created properly with different dictionaries. Unfortunately, afterwards any references to the original dictionaries in the list get overwritten with a reference to rrdict. So in the end, the list contains only references to one single dictionary. Here is some more pythonic and readable way to solve your problem:
lod = [{} for _ in range(len(dataul))]
for rrdict in lod:
for line in datakl:
splt = line.split(',')
rrdict[splt[0]] = splt[1:]
You created the list of dictionaries correctly, as per other answer.
However, when you are updating individual dictionaries, you completely overwrite the list.
Removing noise from your code snippet:
lod = [{} for _ in range(whatever)]
for j in range(whatever):
# rrdict = lod[j] # Uncomment this as a possible fix.
for i in range(whatever):
rrdict[somekey] = somevalue
lod[j] = rrdict
Assignment on the last line throws away the empty dict that was in lod[j] and inserts a reference to the object represented by rrdict.
Not sure what your code does, but see a commented-out line - it might be the fix you are looking for.

List of dictionaries, in a dictionary - in Python

I have a case where I need to construct following structure programmatically (yes I am aware of .setdefault and defaultdict but I can not get what I want)
I basically need a dictionary, with a dictionary of dictionaries created within the loop.
At the beginning the structure is completely blank.
structure sample (please note, I want to create an array that has this structure in the code!)
RULE = {
'hard_failure': {
4514 : {
'f_expr' = 'ABC',
'c_expr' = 'XF0',
}
}
}
pseudo code that needs to create this:
...
self.rules = {}
for row in rows:
a = 'hard_failure'
b = row[0] # 4514
c = row[1] # ABC
d = row[2] # XF0
# Universe collapse right after
self.rules = ????
...
The code above is obviously not working since I dont know how to do it!
Example, that you've posted is not a valid python code, I could only imagine that you're trying to do something like this:
self.rules[a] = [{b:{'f_expr': c, 'c_expr': d}}]
this way self.rules is a dictionary of a list of a dictionary of a dictionary. I bet there is more sane way to do this.
rules = {}
failure = 'hard_failure'
rules[failure] = []
for row in rows:
#this is what people are referring to below. You left out the addition of the dictionary structure to the list.
rules[failure][row[0]] = {}
rules[failure][row[0]]['type 1'] = row[1]
rules[failure][row[0]]['type 2'] = row[2]
This is what I created based on how I understood the questions. I wasn't sure what to call the 'f_expr' and 'c_expr' since you never mention where you get those but I assume they are already know column names in a resultset or structure of some sort.
Just keep adding to the structure as you go.
Your example code doesn't seem to be valid Python. It's not clear if the second level element is supposed to be a list or a dictionary.
However, if you're doing what I think you're doing, and it's a dictionary, you could use a tuple as a key in the top-level dictionary instead of nesting dictionaries:
>>> a = 'hard_failure'
>>> b = 4514
>>> c = "ABC"
>>> d = "XF0"
>>> rules = {}
>>> rules[(a,b)] = {'f_expr' : a,'c_expr' : d}
>>> rules
{('hard_failure', 4514): {'c_expr': 'XF0', 'f_expr': 'hard_failure'}}
My favorite way to deal with nested dictionaries & lists of dictionaries is to use PyYAML. See this response for details.
Well, I apologize for the confusion, I never claimed that code actually compiled, hence (pseudo). Arthur Thomas put me on the right track, here is slightly modified version. (Yes, now its a simply nested dictionary, 3 levels down)
RULE_k = 'hard_failure'
self.rules = {}
for row in rows:
self.rules_compiled.setdefault(RULE_k, {})
self.rules_compiled[RULE_k][row[1]] = {}
self.rules_compiled[RULE_k][row[1]]['f_expr'] = row[0]
self.rules_compiled[RULE_k][row[1]]['c_expr'] = row[1]

Categories