how to subtract a value of a key in python dictionary - python

I'm learning python and I'm trying to use this function I built and its not working. The function is not changing a single value in the dictionary as it is working now, although it should. I'd like to get some help
def delete_product(diction):
product_to_delete = raw_input()
for key,value in diction.items():
if key == product_to_delete:
value = value - 1
if (value == 0):
del diction[key]
print "removed"
raw_input()
print "we couldnt remove the product because it does not exist"
raw_input()

Mistake in this code snippet:
value = value - 1
if (value == 0):
del diction[key]
Instead of modifying value in the dictionary, you are only modifying local value. So, this function will delete the required entry only when value happens to be 1.
You can modify it as follows or any variation of it:
if value == 1:
del diction[key]
break
else:
diction[key] = value - 1
Moreover, please note that you have to break out of the for loop once the entry is deleted from the dictionary. If you modify the dictionary while you are iterating it, the iterator will not work after that. If you want to delete multiple keys in one iteration, first get list of all keys to be deleted within the loop and delete after the loop.

Related

How can a variable check through an empty dictionary

content_ratings = {}
ratings = ['4+', '4+', '4+', '9+', '9+', '12+', '17+']
for c_rating in ratings:
# why is the variable c_rating checking the empty dictionary
if c_rating in content_ratings:
content_ratings[c_rating] += 1
else:
content_ratings[c_rating] = 1
print(content_ratings)
print('Final dictionary:')
print(content_ratings)
#Yuppie, The if is used for verifying if the rating has already been added to the dictionary in a previous loop. If so, it will increment the current value. Otherwise, it will basically initialize it to 1.
Same as eespejel said, c_ratings is the variable that is there to place hold a certain item in the list, going from the first item to the last. Then you do something with the c_ratings variable, like test if c_ratings is already inside the dictionary content_ratings. IF it is already there, increment that score by one. ELSE (if all previous ifs and elifs werent satisfied, set that value to one in the dictionary. This is why when the dictionary is empty, the ELSE is being run, because c_ratings is definitely not in the dictionary, when it is empty.

Trying to delete a key/value pair from JSON within a list

def loop_through_list_keys_and_update_or_delete(body_dict, list_key, key_to_manipulate, update_or_delete):
request_body = body_dict
try:
for keys in request_body[list_key]:
for key, value in keys.items():
if key == key_to_manipulate:
if update_or_delete == 'delete':
del request_body[key]
Hi all! Relatively new to Python, so please be gentle and I definitely appreciate your help! In the attached picture are my run time values. Basically what I am trying to do is delete a specific (but one that changes) key/value pair. The request_body is my json that I've read in.
I am looping on the list 'fxTransactions' and the only keys it is getting are financialTransaction and transactionRefId. In this case, I need to get to the request_body[fxTransactions][0][financialTransaction][rule] field that is within financialTransaction and delete it and its value. But I can't send this as a variable to the delete as you can't combine the list name with the keys in a variable. I can't seem to figure out how to get to this field and delete it. Note that the field/value pair to delete is dynamic so I will not always know which one I want to delete (could be debtor, creditor, etc). I'd also like to use this code for other lists, if possible, so trying not to hard-code. But I can if there is no other way.
Thank you in advance!
Here is code that works to do what I'm trying to do, but I'm trying to come up with a way to make it cleaner and reusable:
index_key_int = int(index_key)
split_key = key.split(".")
keys_numb = len(split_key)
if keys_numb == 5:
del request_body[list_key][index_key_int][split_key[0]][split_key[1]][split_key[2]][split_key[3]][
split_key[4]]
if keys_numb == 4:
del request_body[list_key][index_key_int][split_key[0]][split_key[1]][split_key[2]][split_key[3]]
if keys_numb == 3:
del request_body[list_key][index_key_int][split_key[0]][split_key[1]][split_key[2]]
elif keys_numb == 2:
del request_body[list_key][index_key_int][split_key[0]][split_key[1]]
elif keys_numb == 1:
del request_body[list_key][index_key_int][split_key[0]]
You can use a loop instead of hard-coding all the nested indexing.
obj = request_body[list_key][index_key_int]
for key in split_key[:-1]:
obj = obj[key]
del obj[split_key[-1]]
The for loop dives down into the nested dictionaries. Then it deletes the element with the final key.

Why is dictionary with only keys len zero?

I am trying to make dictionary that are made of only keys. I will populate the value latter. I don't want set. I want key and value data structure. I have variable called legends that has len of 4.
print("len = ",len(my_legends)) # prints 4
plot_param=dict()
plot_param.fromkeys(my_legends)
print("dic len = ", len(plot_param)) # prints 0, I was hoping it to be 4.
for key in plot_param:
print("key == ") # cannot print values at all.
I was planning to loop over the keys and populate its values now I cannot loop at all.
Instead of
plot_param.fromkeys(my_legends)
You probably wanted:
plot_param = dict.fromkeys(my_legends)

Python3: for-loop break and else (if statement)

Background information:
hey,
I want to do the following: I have a dictionary with IDs as keys and lists with various things as value. One of the items of the value is a string. I want to check, if a list contains this string. And I want to do it for all keys in my dictionary.
If the list contains the string, I want to print "String is valid"
If the list does not contain the string, I want to print "String is NOT valid"
So far, so good.
Furthermore, the lists I want to check depend on one console input of the user, which specifies, which list should be checked. The console input is "number".
My idea was to iterate over my dictionary and my list with a nested for-loop and compare, if the string(the item of the value) is equal to any list item. If it is, I want to break out of the loop. If the String is not found in the list, I want to execute the else-statement to print my "String is not valid" message.
Code snippet:
def validationHelper(myDict, myList):
for key in myDict:
for value in myDict[key][0]:
for item in myList:
if value==item:
validationHelper.true="String is valid"
break
else:
validationHelper.true="Warning: String is NOT valid"
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
Problem:
I am running this, but no matter if the string is in the list or not, I always get my printout for the else-statement. So, I guess I have an error in reasoning in my for-loop? Or maybe, I did not understand for-loops at all?! I have tried out different indentions with the else-statement, but couldnt solve my problem.
I would suggest you to change your function the following way (without changing the logic):
def validationHelper(myDict, myList):
for key in myDict:
for value in myDict[key][0]:
for item in myList:
if value==item:
return "String is valid" # Add here to exit
return "Warning: String is NOT valid" # will be returned inf nothing will be found in your 3 loops
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper)
This will help you to exit your 3 nested loops as it was mentioned in comments.
Because in the negative case on first wrong occurrence you don't need to check anything else.
Use return to break all of your loop. Having an else statement is not necessary if you don't have any if statement to begin with.
def validationHelper(myDict, myList):
for item in myList:
if item in myDict.values():
return ("String is valid")
return ("String is NOT valid")
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
elif anyList=="two":
return helperfunc(finalDict,myList2)
elif anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
Using elif instead of multiple if is a better practice. Be careful with indentions next time.
Also you might want to check .keys() and .values()
You can replace:
for key in myDict:
for value in myDict[key][0]:
with:
for value in myDict.values():
The other answers give a good explanation of how to break out of multiple loops. But you could also simplify your code by using Python's built-in functions and list comprehensions, like this:
def validationHelper(myDict, myList):
if any(v in myList for val in myDict.values() for v in val[0]):
validationHelper.true="String is valid"
else:
validationHelper.true="Warning: String is NOT valid"
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
This should be as efficient as your code, since any short circuits at the first match. And it may be a little more readable. (Note that multi-level list comprehensions go in the same order as regular for loops.)

index error while running a loop over list contents

I have a list like this:
my_array= ["*","device",":","xyz"], ["+","asd","=","10","pdf","=","6"],
["+","dsa","=","1","pqa","=","2","dga","=","12"], ["*"]
What I want to do is:
define('device','xyz')
define('asd','10')
define('pdf','6')
define('dsa','1')
define('pqa','2')
define('dga','12')
The way I approached is:
i=0
while i < len(my_array):
if my_array[i][0]=="*":
print("'",my_array[i][1],"'","'",my_array[i][3:],"'")
elif my_array[i][0]=="+":
print("'",my_array[i][1],"'","'",my_array[i][3],"'")
if my_array[i][4]=="\D":
print("'",my_array[i][4],"'","'",my_array[i][6],"'")
elif my_array[i][7]=="\D":
print("'",my_array[i][7],"'","'",my_array[i][9],"'")
i=i+1
But doing this, I get index error. I know where the problem is, but I cannot fix it with my very bad programming brain. Can someone help me on this?
First review problem seems in
if my_array[i][0]=="*":
print("'",my_array[i][1],"'","'",my_array[i][3:],"'")
because last element in your my_array is ['*'] and it has no other elements and u are trying to access my_array['*'][1] and its give index error.
You have to remove that element or add members who fulfill element index requirement.
Hard-coding the indices is a sure sign you're doing something wrong - the items in my_array have variable lengths, so some of your indices inevitably fail. I think what you want is something like:
for command in my_array:
if command[0] in ("*", "+"):
for start in range(1, len(command), 3):
assignment = command[start:start+3]
if assignment[1] in ("=", ":"):
print assignment[0], assignment[2]
It is worth noting, however, that you seem to be attempting to write a file parser. Although this code solves this specific problem, it is likely that your overall approach could be improved.
With the assumption, that every key in your list has a value attached to it(e.g. there are no two asterisk following after each other) you can make some simplifications:
We'll read the first value as a key of a new dict and the second item as the value.
With the newly tidied up dict(d) you can continue to work easily e.g. in a for loop:
array=["*","device",":","xyz"], ["+","asd","=","10","pdf","=","6"],
["+","dsa","=","1","pqa","=","2","dga","=","12"], ["*"]
d = {}
for list in array:
new_key = None
for item in list:
if item in ['*',':','+','=']: continue
if new_key == None:
new_key = item
else:
d[new_key] = item
new_key = None
for key in d:
define(key,d[key])

Categories