Python: update dictionary key with tuple values - python

I have a dictionary that has keys with two values each. I need to update the second value as pass duplicate keys.
Clearly what I'm trying isn't working out.
if value1 not in dict.keys():
dict.update({key:(value1,value2)})
else:
dict.update({key:value1,+1)})
this just returned a diction with 1s for value 2 instead of incrementing by 1

The expression +1 doesn't increment anything, it's just the number 1
Also avoid using dict as a name because it's a Python built-in
Try structuring your code more like this:
my_dict = {} # some dict
my_key = # something
if my_key not in my_dict:
new_value = # some new value here
my_dict[my_key] = new_value
else:
# First calculate what should be the new value
# Here I'm doing a trivial new_value = old_value + 1, no tuples
new_value = my_dict[my_key] + 1
my_dict[my_key] = new_value
# For tuples you can e.g. increment the second element only
# Of course assuming you have at least 2 elements,
# or old_value[0] and old_value[1] will fail
old_value = my_dict[my_key] # this is a tuple
new_value = old_value[0], old_value[1] + 1
my_dict[my_key] = new_value
There may be shorter or smarter ways to do it, e.g. using the operator +=, but this snippet is written for clarity

Related

I just want to print the key, not their index

I need to print the keys + their values and it always prints the index of the key too, how can I fix that?
def task_3_4(something:str):
alphabet =list(string.ascii_letters)
i = 0
k=0
while i < len(alphabet):
dicts = {alphabet[i]: 0}
count = something.count(alphabet[i])
dicts[i] = count
if 0 < count:
for k in dicts:
print(k)
i = i+1
Based on the code it seems like you are trying to do some sort of counter of different characters in the string?
There is no index. your "index" is the "i" iterator you are using for your while loop. This simply makes a new key in dicts as called by dicts[i]. Thus when you call the print loop, it just iterates through and reads out I as well.
Try:
dicts[alphabet[i]] = count
Also your print function only prints out the key of the dict entry instead of the key-value pair. to do that you can try:
for k in dicts:
print(k,dicts[k])
Try reading up on the python docs for dicts.
https://docs.python.org/3/tutorial/datastructures.html

Removing specific dictionary values inside a loop

I'm trying to make a context-free grammar simplification software.
I'm stuck when it comes to delete some specific items from the dictionary's values or even the key value pair.
The problem is that it doesn't follow a pattern.
If the element belongs to V1, I need to keep it in dictionary.
(V1 is the list of all values who derivates a terminal, those guys are the only ones I need to keep on my dictionary, but it's not that simple)
If the element doesn't belongs to V1 and dictionary's values is a string, I need to remove the element.
If the element doesn't belongs to V1 and dictionary's values is a list, I need to check if it's the single element of that list, if so, delete Value.
The failed loop is down here.
I printed the parts that I can't figure out the logic in modifying the dictionary.
counter = 0
for k,v in derivations.items():
derivationsCount = len(v)
while counter < derivationsCount:
if lista_ou_string(v[counter]): # returns True for lists, False for else
sizeOfList = len(v[counter])
counter2 = 0
while counter2 <= (sizeOfList - 1):
if v[counter][counter2] not in V1:
if derivationsCount == 1:
print("# NEED TO DELETE BOTH KEY AND VALUE FROM derivatios.items()")
else:
print("# NEED TO DELETE ONLY THE VALUE FROM derivations.items()")
counter2 += 1
else: # strings \/
if v[counter] not in V1:
if derivationsCount == 1:
print("# NEED TO DELETE BOTH KEY AND VALUE FROM derivatios.items()")
else:
print("# NEED TO DELETE ONLY THE VALUE FROM derivations.items()")
else:
print("# DO NOT DELETE ANYTHING! ALL LISTS ELEMENTS BELONGS TO 'V1'")
counter += 1
One does not want to modify a dictionary (or list) while looping over it. Therefore I create a copy of the derivations - new_derivations and modify this new_derivations:
import copy
new_derivations = copy.deepcopy(derivations)
for k, v in derivations.items():
for vi in v:
if (lista_ou_string(vi) and not set(vi).issubset(V1)) or vi not in V1:
if len(v) == 1:
# NEED TO DELETE BOTH KEY AND VALUE FROM derivatios.items()
del new_derivations[k]
break
else:
# NEED TO DELETE ONLY THE VALUE FROM derivations.items()
idx = new_derivations[k].index(vi)
del new_derivations[k][idx]
I would actually implement the above code differently: instead of thinking in terms of removing items from derivations, think instead of when an element should be added to the list. Then the code becomes much simpler:
new_derivations = {}
for k, v in derivations.items():
nv = [vi for vi in v if ((isinstance(vi, list) and set(vi).issubset(V1))
or vi in V1)]
if nv:
new_derivations[k] = nv
if you want to delete a key,value pair from a dictionary, use del:
>>> my_dictionary = {'foo':'bar', 'boo':'baz'}
>>> del my_dictionary['foo']
>>> my_dictionary
{'boo': 'baz'}
if you want to delete the value, but keep the key, you can try assigning key None:
>>> my_dictionary = {'foo':'bar', 'boo':'baz'}
>>> my_dictionary['foo'] = None
>>> my_dictionary
{'foo': None, 'boo': 'baz'}

How to iterate over a dictionary to make new for loop for the remaining elements?

I am trying to make a new dictionary from the one which I'm having.
`dict1 = {'A':{}, 'B':{}, 'C':{}, 'D':{}, 'E':{}}
for key, val in dict1.iteritems():
mytest = key
newConditionFlag = getSummary(mytest)
if newConditionFlag == 1:
make dict2`
where getSummary function is as follows:
`def getSummary(mytest):
newConditionFlag==0
bVal = mytest.CanClose()
if bVal == True:
pass
else:
newConditionFlag=1
return newConditionFlag`
If newConditionFlag == 1 for B, then my dict2 should be
dict2 = 'C':{}, 'D':{}, 'E':{}}.
In the same way if newConditionFlag == 1 for C,
dict2 = 'D':{}, 'E':{}}.
How should I do this?
I know for a simple condition if we want to access remaining values what we do is
`l = [1,2,3,4,5]
for i,j in zip(l, l[2:]):
print j`
But what should be done in case of dictionary? If we try it the same way it gives TypeError: unhashable type
The only way this could possibly make sense is to convert the dictionary to a list first. Do your processing on the list, then convert back to a dictionary.
l = sorted(dict1.items())
# do your thing
dict1 = dict(l)

Python Group by count

Given a dictionary, I need some way to do the following:
In the dictionary, we have names, gender, occupation, and salary. I need to figure out if each name I search in the dictionay, there are no more than 5 other employees that have the same name, gender and occupation. If so, I output it. Otherwise, I remove it.
Any help or resources would be appreciated!
What I researched:
count = Counter(tok['Name'] for tok in input_file)
This counts the number of occurances for name (ie Bob: 2, Amy: 4). However, I need to add the gender and occupation to this as well (ie Bob, M, Salesperson: 2, Amy, F, Manager: 1).
To only check if the dictionary has 5 or more (key,value) pairs, in which the name,gender and occupation of employee is same, is quite simple. To remove all such inconsistencies is tricky.
# data = {}
# key = 'UID'
# value = ('Name','Male','Accountant','20000')
# data[key] = value
def consistency(dictionary):
temp_list_of_values_we_care_about = [(x[0],x[1],x[2]) for x in dictionary.itervalues()]
temp_dict = {}
for val in temp_list_of_values_we_care_about:
if val in temp_dict:
temp_dict[val] += 1
else:
temp_dict[val] = 1
if max(temp_dict.values()) >=5:
return False
else:
return True
And to actually, get a dictionary with those particular values removed, there are two ways.
Edit and update the original dictionary. (Doing it in-place)
Create a new dictionary and add only those values which satisfy our constraint.
def consistency(dictionary):
temp_list_of_values_we_care_about = [(x[0],x[1],x[2]) for x in dictionary.itervalues()]
temp_dict = {}
for val in temp_list_of_values_we_care_about:
if val in temp_dict:
temp_dict[val] += 1
else:
temp_dict[val] = 1
new_dictionary = {}
for key in dictionary:
value = dictionary[key]
temp = (value[0],value[1],value[2])
if temp_dict[temp] <=5:
new_dictionary[key] = value
return new_dictionary
P.S. I have chosen the much easier second way to do it. Choosing the first method will cause a lot of computation overhead, and we certainly would want to avoid that.

Using decorators vs iteration to set values?

So I have to loop through a list of objects, using some of their values to do computation, and then assign them new values.
Because many of the items in the list will be assigned the same new value, I used a dictionary to hold the list of items that will require the same value. For example:
item_dict = {}
for item in list:
value = item.value
if value not in item_dict:
item_dict[value] = [item]
else:
item_dict[value].append(item)
# do some calculations base on values
new_data # some dictionary created by computation
# new data is stored new_data[value] = new_value
for value, new_value in new_data.items():
items = item_dict[value]
for item in items:
item.value = new_value
I was think about removing the for item in items loop with a decorator since all the new_value(s) for that list are the same. For example:
def dec(item):
def wrap(value):
item.value = value
return wrap
def rec(item, func):
def wrap(value):
item.value = value
func(value)
return wrap
item_dict = {}
for item in list:
value = item.value
if value not in item_dict:
item_dict[value] = dec(item)
else:
item_dict[value] = rec(item, item_dict[value])
# do some calculations base on values
new_data # some dictionary created by computation
# new data is stored new_data[value] = new_value
for value, new_value in new_data.items():
items = item_dict[value]
items(new_value)
Would the decorator fashion be more efficient and how much of a memory impact will it have? Are there any better ways of doing this?
A defaultdict works well here:
from collections import defaultdict
item_dict = defaultdict(list)
for item in value_list:
item_dict[item.value].append(item)
# do some calculations base on values
new_data # some dictionary created by computation
# new data is stored new_data[value] = new_value
for value, new_value in new_data.items():
for item in item_dict[value]:
item.value = new_value
I struggle to think of a way the decorator version could be better - for one thing, you have to worry about the recursion limit.
The get method works well in the first case.
item_dict = {}
for item in list:
item_dict[item.value] = item_dict.get(item.value, []) + [item]
The key to making this work is to use list addition instead of append, as append returns None.

Categories

Resources