Expect alternate solution to update the Dictionary with given reference dictionary - python

I am trying to update the dictionary "menu" values by getting a value from an appropriate dictionary. I try the following code and get the desired result. But I expect some other alternate ways and a more generic solution in a pythonic way.
Code
language = {"english" : {"lbl01":"File" ,"lbl02":"Accounts"},
"tamil" : {"lbl01":"கோப்பு" ,"lbl02":"கணக்கியல்"},
"hindi" : {"lbl01":"Hindi_File","lbl02":"Hindi_accounts"}}
scut = {"user1": {"lbl01":"Alt+F","lbl02":"F5"},
"user2": {"lbl01":"Ctrl+F","lbl02":"Shift+F5"}}
menu = {"lbl01" :{"id":"file" ,"lan1":"","lan2":"","scut":""},
"lbl02" :{"id":"accounts","lan1":"","lan2":"","scut":""}}
user = ["user2"]
selected_lan = ["tamil","hindi"]
menukey_lst,submenukey_lst =[],[]
for menukey,menuvalue in menu.items():
if menukey not in menukey_lst: menukey_lst.append(menukey)
for submenukey,submenuvalue in menuvalue.items():
if submenukey not in submenukey_lst: submenukey_lst.append(submenukey)
for index,mk in enumerate(menu.keys()):
for item in submenukey_lst:
menu[menukey_lst[index]]["lan1"] = language[selected_lan[0]][menukey_lst[index]]
menu[menukey_lst[index]]["lan2"] = language[selected_lan[1]][menukey_lst[index]]
menu[menukey_lst[index]]["scut"] = (scut[user[0]][mk])
print(menu)
Output
{'lbl01': {'id': 'file', 'lan1': 'கோப்பு', 'lan2': 'Hindi_File', 'scut': 'Ctrl+F'}, `'lbl02': {'id': 'accounts', 'lan1': 'கணக்கியல்', 'lan2': 'Hindi_accounts', 'scut': 'Shift+F5'}}`

This should work.
for key, value in menu.items():
for sub_key in value.keys():
if sub_key == 'lan1':
value[sub_key] = language[selected_lan[0]][key]
elif sub_key == 'lan2':
value[sub_key] = language[selected_lan[1]][key]
elif sub_key == 'scut':
value[sub_key] = scut[user[0]][key]

Related

Django/Python Multiple records

I have a program that compares values from the database and from a CSV file. My program works like this.
Database has values.
User uploads a file (multiple users multiple
files).
The program compares the values from the database and the
CSV files and gives an output.
Which tells me that this particular value was found in this user's file.
But I want the program to show me that if the value was found in the other user's file or not.
Here is a working example.
DB Values = [1,23,33,445,6656,88]
Example values of the CSV files:
File 1 values = [1,23,445,77,66,556,54]
File 2 values = [1,23,45,77,366]
File 3 values = [1,23,5,77,5356,524]
Output needed:
{'1':[(user1, some value),(user2, some value)...]}
Here my code:
def LCR(request):
template = "LCR\LCRGen.html"
dest = Destination.objects.values_list('dest_num', flat=True)
ratelist = { }
csv_file = { }
data_set = { }
io_string = { }
vendor = RateFile.objects.values_list()
v_count = vendor.count()
for v_id, v_name, v_file in vendor:
vendor_name = str(v_name)
vendornames = str(v_name)
vendornames = { }
for desNum in dest:
desNum = str(desNum)
for countvar in range(v_count):
csv_file[vendor_name] = RateFile.objects.get(id=v_id).ven_file
data_set[vendor_name] = csv_file[vendor_name].read().decode("UTF-8")
io_string[vendor_name] = io.StringIO(data_set[vendor_name])
next(io_string[vendor_name])
for column in csv.reader(io_string[vendor_name], delimiter=str(u",")):
vendornames[column[0]] = column[1]
for venNum, venValue in vendornames.items():
venlen = len(venNum)
deslen = len(desNum)
if venlen >= deslen or venlen <= deslen:
if desNum[:-1] == venNum[:-1] and desNum[:-2] == venNum[:-2] and desNum[:-3] == venNum[:-3]:
ratelist[desNum] = [(vendor_name, venValue),]
if (vendor_name, venValue) in ratelist[desNum]:
ratelist[desNum] = [
(vendor_name, venValue),]
elif desNum[:-1] == venNum[:-2] and desNum[:-2] == venNum[:-3] and desNum[:-3] == venNum[:-4]:
ratelist[desNum] = [(vendor_name, venValue),]
if (vendor_name, venValue) in ratelist[desNum]:
ratelist[desNum] = [
(vendor_name, venValue),]
elif desNum[:-1] == desNum[:-3] and desNum[:-2] == venNum[:-4] and desNum[:-3] == venNum[:-5]:
ratelist[desNum] = [(vendor_name, venValue),]
elif desNum[:-1] == venNum[:-5] and desNum[:-2] == venNum[:-6]:
ratelist[desNum] = [(vendor_name, venValue),]
if (vendor_name, venValue) in ratelist[desNum]:
ratelist[desNum] = [
(vendor_name, venValue),]
else:
pass
print ( ratelist )
return render ( request, template, { "ratelist" : ratelist } )
Output
Zong, Tata are usernames and the float values is their respective value for the key value of the dictionary.
{'12': [('Zong', ' 0.026')], '213': [('Tata', ' 4.150')], '49': [('Tata', ' 0.531')], '30': [('Zong', ' 0.87')], '454': [('Tata', ' 0.531')], '374': [('Zong', ' 0.87')],
This is what you asked for:
### your data example
db = [1,23,33,445,66,556,88]
us1 = [1,23,445,77,66,556,54]
us2 = [1,23,45,77,366]
### create a list of usernames (to use the string name in dictionary)
userlist = [ "us1", "us2" ]
### intialize the dict for results
values_dict = {}
### open the loop on DB values
for value in db :
# open loop on userlist
for user in userlist :
# if value is found in user list of values
if value in eval(user) :
# if values still NOT a key of results dictionary create the key with the tuple list as values
if value not in values_dict :
values_dict.update({ value : [ ( user, value ) ] })
# else just append the tuple (username, value) to the results dictionary for the DB value corresponding key
else :
values_dict[value].append([ ( user, value ) ])
values_dict
### OUTPUT:
{1: [('us1', 1), [('us2', 1)]], 23: [('us1', 23), [('us2', 23)]], 445: [('us1', 445)], 66: [('us1', 66)], 556: [('us1', 556)]}
but it makes no sense cause it simply check if a value is in the user list of values and add a tuple just to confirm it, it doesn't require all this code, could be simplified a lot. But I'm thinking that I misunderstood your question (please review the english), probably you need to use the DB value as the key to retrieve another value from the user...please review and update

What is the most efficient way to a multiple variable in dictionary in python?

this my code, i'm looking, is other way to code this in most efficient way?
i have multiple variables and inserted to the dictionary.
please feel to suggest and other options like array and etc will do.
def momentEndSpan(span_type,max_combo,length):
if "simply supported" == span_type:
q = max_combo
force = {}
RA = {"PA" : q*length/2}
RB = {"PB" : q*length/2}
RA_moment = {"MA" : 0}
R_mid_moment = {"Mmid": (q*math.pow(length,2))/8 }
RB_moment = { "MB" : 0}
force.update(RA)
force.update(RB)
force.update(RA_moment)
force.update(R_mid_moment)
force.update(RB_moment)
return force
elif "one end continuous" == span_type:
q = max_combo
x = (3/8)*length
force = {}
RA = {"Phinge" : 3*q*length/8}
RB = {"Pfixed" : 5*q*length/8}
RA_moment = {"Mhinge" : 0}
R_mid_moment = {"Mmid": (q*math.pow(length,2))*(9/128) }
RB_moment = { "MB" : -1*(q*math.pow(length,2))/8 }
force.update(RA)
force.update(RB)
force.update(RA_moment)
force.update(R_mid_moment)
force.update(RB_moment)
return force
Thank you very much
The "More Pythonic" way is to create one dictionary and update once.
q = max_combo
force = {}
if "simply supported" == span_type:
new = {"PA" : q*length/2,
"PB" : q*length/2,
"MA" : 0, "Mmid": (q*math.pow(length,2))/8,
"MB" : 0}
elif "one end continuous" == span_type:
x = (3/8)*length
new = {"Phinge" : 3*q*length/8,
"Pfixed" : 5*q*length/8,
"Mhinge" : 0,
"Mmid": (q*math.pow(length,2))*(9/128),
"MB" : -1*(q*math.pow(length,2))/8 }
force.update(new)
Also, note that if the force dictionary doesn't contain any previously defined items you can simply return the new and/or just continue to update the new in your next operations if there are any. Or just use name force instead of new.
q = max_combo
if "simply supported" == span_type:
force = {...}
elif "one end continuous" == span_type:
x = (3/8)*length
force = {...}

How to remove dict keys if value is empty

In my form post request I'm grabbing all form info, but it seems as though there are some empty keys and values. I'd like to remove all instances of empty keys and values. This what I have so far, and it's obviously not working.
post_dict = dict(request.POST)
item_data = {}
for key, value in post_dict.items():
if value is None:
del post_dict[key]
field = key.split('[')[1].replace(']', '')
item_data[field] = ''.join(value)
print(item_data)
What the print item_data looks like:
{'': '', 'username': 'johndoe', 'email': 'johndoe#gmail.com', ...
If you delete the key, will it delete its respective value? How can I get rid of empty keys and values?
Try this:
new_item_data={k:item_data[k] for k in item_data if item_data[k]}
Any keys that do not have values will be removed.
Maybe you can do what you want using one of these:
dict_1 = {'': '', 'username': 'johndoe', 'email':'', }
dict_2 = dict(x for x in dict_1.iteritems() if any(x))
print dict_2 # {'username': 'johndoe', 'email': ''}
dict_3 = dict(x for x in dict_1.iteritems() if all(x))
print dict_3 # {'username': 'johndoe'}
for key, value in post_dict.items():
In your code you are iterating on post_dict.
However, in the line del post_dict[key] you are modifying the iterator, so it will provide an inconsistent view of the dictionary to for. It is not good to add or delete keys to the dictionary that you are iterating on.
This may give the result you wanted
post_dict = dict(request.POST)
item_data = {}
for key, value in post_dict.items():
if value == "":
continue
if key == "":
continue
field = key.split('[')[1].replace(']', '')
item_data[field] = ''.join(value)
print(item_data)
Try this,
post_dict = {'': '', 'item_data[username]': ['johndoe'], 'item_data[email]': ['johndoe#gmail.com'], 'item_data[campus]': ['madison']}
item_data = {}
for key, value in post_dict.items():
strlist = key.split('[')
if len(strlist) == 1:
continue
new_key = strlist[1].replace(']', '')
new_value = ''.join(value)
# add to the dict if both new_key and new_value are non-empty
if all([new_key, new_value]):
item_data[new_key] = new_value
print(item_data)
# Output
{'username': 'johndoe', 'campus': 'madison', 'email': 'johndoe#gmail.com'}
Previous answer: Delete those items from a dict whose key or value is empty.
d = {'': '', 'username': 'johndoe', 'email': 'johndoe#gmail.com'}
for k, v in d.items():
if not any([k, v]):
del d[k]
print(d)
{'username': 'johndoe', 'email': 'johndoe#gmail.com'}

Python dictionary print with parentheses

I am trying to edit this function so the values of the dictionary will not be printed in parentheses and will be iterable:
def traverse_appended(key):
reg_dict = {}
#keypath = r"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
for item in traverse_reg(key):
keypath_str = str(keypath+item)
reg_dict[item] = str(get_reg("Displayversion", keypath_str)), str(get_reg("DisplayName", keypath_str))
#reg_dict[item] = get_reg("DisplayName", keypath_str)
return reg_dict
the expected output is :
{'DXM_Runtime': 'None', 'None'}
The function output:
{'DXM_Runtime': ('None', 'None')}
#Consider traverse_appended returns following dict.
#I think, converting func_dict values which are tuple into string, will help you to get expected output.
func_dict = {"DXM_Runtime":('None','None'),
"TMP_KEY":('A','B')
}
derived_dict = {}
for k,v in func_dict.viewitems():
tmp_str = ",".join(v)
derived_dict[k] = tmp_str
print derived_dict
#Output
E:\tmp_python>python tmp.py
{'DXM_Runtime': 'None,None', 'TMP_KEY': 'A,B'}
#If this doesn't help you, then please post the code for get_reg and traverse_reg function also.

python generating nested dictionary key error

I am trying to create a nested dictionary from a mysql query but I am getting a key error
result = {}
for i, q in enumerate(query):
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email
error
KeyError: 'data'
desired result
result = {
'data': {
0: {'firstName': ''...}
1: {'firstName': ''...}
2: {'firstName': ''...}
}
}
You wanted to create a nested dictionary
result = {} will create an assignment for a flat dictionary, whose items can have any values like "string", "int", "list" or "dict"
For this flat assignment
python knows what to do for result["first"]
If you want "first" also to be another dictionary you need to tell Python by an assingment
result['first'] = {}.
otherwise, Python raises "KeyError"
I think you are looking for this :)
>>> from collections import defaultdict
>>> mydict = lambda: defaultdict(mydict)
>>> result = mydict()
>>> result['Python']['rules']['the world'] = "Yes I Agree"
>>> result['Python']['rules']['the world']
'Yes I Agree'
result = {}
result['data'] = {}
for i, q in enumerate(query):
result['data']['i'] = {}
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email
Alternatively, you can use you own class which adds the extra dicts automatically
class AutoDict(dict):
def __missing__(self, k):
self[k] = AutoDict()
return self[k]
result = AutoDict()
for i, q in enumerate(query):
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email
result['data'] does exist. So you cannot add data to it.
Try this out at the start:
result = {'data': []};
You have to create the key data first:
result = {}
result['data'] = {}
for i, q in enumerate(query):
result['data'][i] = {}
result['data'][i]['firstName'] = q.first_name
result['data'][i]['lastName'] = q.last_name
result['data'][i]['email'] = q.email

Categories