Increasing values in a dictionary? - python

Is there a function which can take in a dictionary and modify the dictionary by increasing only the values in it by 1?
i.e
f({'1':0.3, '11':2, '111':{'a':7, 't':2}})
becomes
{'1':1.3, '11':3, '111':{'a':8, 't':3}}
and
f({'a':{'b':{'c':5}}})
becomes
{'a':{'b':{'c':6}}}
Thanks!

Not the best...
def incr(d):
try:
return d + 1
except TypeError: # test the type rather catch error
return g_incr(d)
except:
return 0
def g_incr(d):
return {k:incr(v) for k, v in d.items()}
test = {'1':0.3, '11':2, '111':{'a':7, 't':2}}
print g_incr(test)

I think you should try this;
def increment(dict):
return {k:v+1 for k,v in dict.items()}
result = increment()
print result

Related

Count frequency of item in tuple with kwargs**

This is what I wrote:
def count_passes(**kwargs)
count = 0 #Complete this function to count the number of passes
for pas in kwargs:
if pas == mark:
count = count + 1
return
result = count_passes(math="Fail", science="Fail", history="Pass", english="Pass")
print(f'The number of passes: {count_occurrence(result, "Pass")}')
How do I make it to count how often 'Pass' is in kwargs?
You seem to be missing some code from the question, but here is how you can do the count:
def count_occurrences(mark, **kwargs):
count = 0 # Complete this function to count the number of passes
for key, value in kwargs.items():
if value == mark:
print(f"Passed {key}")
count = count + 1
return count
kwargs is a dict so you need to address it's items() or values() when iterating. Otherwise you're just going through the keywords. Also the return statement should be after the loop and actually return the count as a value.
In case you wanted to improve on the implementation, here is a lighter way to do the same thing:
def count_occurrences_simpler(mark, **kwargs):
return sum(1 for v in kwargs.values() if v == mark)
Then just call the function and print the result like you were doing
result = count_occurrences("Pass", math="Fail", science="Fail", history="Pass", english="Pass")
print(f'The number of passes: {result}')
kwargs is a dictionary of values:
{"math":"Fail", "science":"Fail", "history":"Pass", "english":"Pass"}
in your example.
When you iterate over that dictionary, your are only getting the keys: "math", "science", etc.
To get the value associated with that key, you need to get it from the original dict: kwargs[pas] in your case.
Also, notice that in your code, you are not returning any value, so you are dropping all the work your function is doing to compute count.
Finally, you are returning in your for loop, right after you've started it, so you need to return at the end of the loop
However, in your case you can use kwargs.items() to get both the key and the values for instance, or even kwargs.values(), since you don't actually use the key in your code:
mark = "Pass"
def count_passes(**kwargs)
count = 0 #Complete this function to count the number of passes
for pas in kwargs.values():
if pas == mark:
count = count + 1
return count
result = count_passes(math="Fail", science="Fail", history="Pass", english="Pass")
print(f'The number of passes: {count_occurrence(result, "Pass")}')
kwargs is a dictionary, so you need to check the values. One option is to convert the values to a list and use the count function
def count_passes(**kwargs):
return list(kwargs.values()).count('Pass')

Using dictionary for conditional assignment

How can I use dictionary as a conditional statement to change the value of the variable?
for example:
a = 20
dicta = {10:3, 20:2, 30:1}
#compare using first pair as the value of a, such that:
if a=10: assign a=3
if a=20: assign a=2
if a=30: assign a=1
Thankyou!
If you can be sure that the value of a is actually a key in the dict:
a = dicta[a]
or to have an additional check:
if a in dicta:
a = dicta[a]
else:
print("error, value {} not in dictionary".format(a))
Try this:
a = 20
for k, v in dicta.items():
if k == a:
a = v
break

Return next key of a given dictionary key, python 3.6+

I am trying to find a way to get the next key of a Python 3.6+ (which are ordered)
For example:
dict = {'one':'value 1','two':'value 2','three':'value 3'}
What I am trying to achieve is a function to return the next key. something like:
next_key(dict, current_key='two') # -> should return 'three'
This is what I have so far:
def next_key(dict,key):
key_iter = iter(dict) # create iterator with keys
while k := next(key_iter): #(not sure if this is a valid way to iterate over an iterator)
if k == key:
#key found! return next key
try: #added this to handle when key is the last key of the list
return(next(key_iter))
except:
return False
return False
well, that is the basic idea, I think I am close, but this code gives a StopIteration error. Please help.
Thank you!
An iterator way...
def next_key(dict, key):
keys = iter(dict)
key in keys
return next(keys, False)
Demo:
>>> next_key(dict, 'two')
'three'
>>> next_key(dict, 'three')
False
>>> next_key(dict, 'four')
False
Looping while k := next(key_iter) doesn’t stop correctly. Iterating manually with iter is done either by catching StopIteration:
iterator = iter(some_iterable)
while True:
try:
value = next(iterator)
except StopIteration:
# no more items
or by passing a default value to next and letting it catch StopIteration for you, then checking for that default value (but you need to pick a default value that won’t appear in your iterable!):
iterator = iter(some_iterable)
while (value := next(iterator, None)) is not None:
# …
# no more items
but iterators are, themselves, iterable, so you can skip all that and use a plain ol’ for loop:
iterator = iter(some_iterable)
for value in iterator:
# …
# no more items
which translates into your example as:
def next_key(d, key):
key_iter = iter(d)
for k in key_iter:
if k == key:
return next(key_iter, None)
return None
You can get the keys of the dictionary as list and use index() to get the next key. You can also check for IndexError with try/except block:
my_dict = {'one':'value 1','two':'value 2','three':'value 3'}
def next_key(d, key):
dict_keys = list(d.keys())
try:
return dict_keys[dict_keys.index(key) + 1]
except IndexError:
print('Item index does not exist')
return -1
nk = next_key(my_dict, key="two")
print(nk)
And you better not use dict, list etc as variable names.
# Python3 code to demonstrate working of
# Getting next key in dictionary Using list() + index()
# initializing dictionary
test_dict = {'one':'value 1','two':'value 2','three':'value 3'}
def get_next_key(dic, current_key):
""" get the next key of a dictionary.
Parameters
----------
dic: dict
current_key: string
Return
------
next_key: string, represent the next key in dictionary.
or
False If the value passed in current_key can not be found in the dictionary keys,
or it is last key in the dictionary
"""
l=list(dic) # convert the dict keys to a list
try:
next_key=l[l.index(current_key) + 1] # using index method to get next key
except (ValueError, IndexError):
return False
return next_key
get_next_key(test_dict, 'two')
'three'
get_next_key(test_dict, 'three')
False
get_next_key(test_dict, 'one')
'two'
get_next_key(test_dict, 'NOT EXISTS')
False

Printing a dictionary value of a function in another function

I'm trying to write a looping function that prompts the user to enter a key from the first function and if it is is a key then it prints its value. If the word entered is not in the dictionary it returns "No entry".
What I have so far.
def read_ticker():
c = {}
with open('tickers.csv') as f:
for line in f:
items = [item.strip('"').strip() for item in line.split(",")]
c[items[0]] = items[1:]
print(c)
read_ticker()
d = read_ticker()
def ticker():
x = input('Ticker: ')
if x in d:
return x[c]
else:
return 'No entry'
ticker()
How can I return the value of the key entered in the second function?
You never return your dictionary in read_ticker, and it's unclear why you're calling the function twice.
Where print(c) is put return c.
And I think you want to index the dict instead of indexing the input.
Also, what is c that you're indexing with? This is undefined. I'm assuming this is meant to be the dictionary as defined in read_ticker. In which case you want d[x].
The dictionary c isn't global, although you could define it to be, so you can't access it in your other function by c (ignoring that the indexing is backwards even if possible). Instead, since the dictionary is local to the function read_ticker and modified there we return the dictionary and store it in the variable d.
Your read_ticker() function should return c:
def read_ticker():
c = {}
with open('tickers.csv') as f:
for line in f:
items = [item.strip('"').strip() for item in line.split(",")]
c[items[0]] = items[1:]
print(c)
return c
and then you can modify your ticker function as follows:
def ticker():
x = input('Ticker: ')
if x in d.keys():
return d[x]
else:
return 'No entry'
Your ticker function can use get, which allows you to give a value if the key doesn't exist, like this:
def ticker():
x = input('Ticker: ')
return d.get(x, "No entry")

K-way-merge without heapq and any other libraries using python

Can anyone tell me what's wrong with my code? Input is n iterators. I need to make generator which yields values of merged list on fly. I don't want use heapq, queue or deque.
#!/usr/bin/python
def min_(ar):
l = list()
for val, array in ar:
l.append(val)
return l.index(min(l))
def k_way_merge(*args):
data = list()
for array in args:
data.append((array.next(), array))
while data:
index = min_(data)
key, value = data[index]
data.remove(data[index])
yield key
if value:
data.append((next(value), value))
l=[[1,3], [2,4], [10,100],[100,101]]
res = k_way_merge(iter(l[0]), iter(l[1]),iter(l[2]),iter(l[3]))
for i in res:
print i
result is:
1
2
3
It seems that next(value) raises StopIteration, but how to repair all that...Help
iterators don't evaluate to False when they are empty. You have to use the next builtin with a sentinel value:
END = object()
while data:
index = min_(data)
key, value = data.pop(index)
yield key
key = next(value, END)
if key is not END:
data.append((key, value))
Also, since min_ returns the index, why use data.remove(data[index]) - just use pop.
You need to make this operation optional if value is empty:
if value:
data.append((next(value), value))
This change works for me:
if value:
try:
data.append(next(value), value)
except StopIteration:
pass

Categories