Difficulty with dictionary order function - python

Write a function named "indexed_kvs" that doesn't take any parameters and returns a new key-value store containing the integers from 0 to 36 as values each stored at a key which is a string containing the digits of the integer. For example the key-value "0":0 will be in your returned key-value store (include both 0 and 36 in your list). (My code below)
def indexed_kvs():
d = dict()
for x in range(37):
d[x] = x
return d
I keep on getting the first key and value; how do I get all the keys and values?

You return from inside the loop which is a common mistake that can be avoided altogether by using a dict comprehension, at least in this simple case:
def indexed_kvs():
return {str(x): x for x in range(37)}

As #Loocid comment, the return statement shouldn't be inside the for loop, so the correct code would be:
def indexed_kvs():
d = dict()
for x in range(37):
d[str(x)] = x
return d

You have your "return d", inside you loop. So, what happens is that -
1) The function begins
2) The for loop executes once:
a) adds 0 to the dictionary at key 0,
b) encounters return d, them thinks- 'Okay! I got a return statement. I gotta exit! '
c) And Boom! Your function is done with
So, just move your return d out of you for loop. So, the exiting of the function will take place when, the loop is over.
So your new code should be:
def indexed_kvs():
d = dict()
for x in range(37):
d[str(x)] = x
return d

Related

Can I run the same function multiple times with the return value as the argument?

The code is supposed to return a final color value if you give it a string of colours, like
Colour here: GG, BG, RG, BR
Becomes colour: G, R, B, G
For example: 'RGBG' would return 'B'
Here, i wrote a function to assign color tags (Assign) and another funtion which would feed the broken down primary string. It all works fine when i manually type the new_value = assign(main(again)) multiple times depending on the size of the primary string(RGBG -> BRR -> GR ->B; 4 times here but i run the first iteration in advance because the again parameter would have a value to begin with), but returns an empty value when i use again = assign(main(again)) even though i have given the parameter a value on the previous lines so it's not a "undefined param" error.. i think.
I'm pretty new to this and would greatly appreciate it if you could point me in the right way. Hoping this message finds you in safety :)
def assign(xlist):
for x in range(len(xlist)):
if xlist[x] in ('BG', 'GB', 'RR'): xlist[x] = 'R'
elif xlist[x] in ('RG', 'GR', 'BB'): xlist[x] = 'B'
elif xlist[x] in ('BR'. 'RB', 'GG'): xlist[x] = 'G'
return ''.join(xlist)
def main(xrow):
nrow = []
for i in range(len(xrow)-1):
nrow.append(xrow[i] + xrow[i+1])
return(nrow)
def triangle(row):
global again
again = assign(main(row))
print(row)
print(again)
for k in range(len(row)-1):
again = assign(main(again))
return again
You could do it like this:
s = 'RGBG'
dict_map = {
'BG':'R',
'GB':'R',
'RR':'R',
'RG':'B',
'GR':'B',
'BB':'B',
'BR':'G',
'RB':'G',
'GG':'G'
}
def process(s):
while len(s)!=1:
s = "".join([dict_map["".join(x)] for x in zip(s[:-1], s[1:])])
return s
print(process(s))
# B
Lets break it down:
you can use a dictionary to translate values to other values based on their keys:
dict_map["BG"] will return "R". To use the dict we need a list of elements with 2 characters.
We create that list by using the following: [x for x in zip(s[:-1], s[1:])] This will return a list of overlapping tupels. E.g. ("R", "G")
Since we cant use this tupels with the dictionary we "".join() them together resulting e.g. in "RG".
Now we ask the dictionary which values is used for that key by using dict_map["RG"] and get "R" in this case.
The whole thing is done here: [dict_map["".join(x)] for x in zip(s[:-1], s[1:])]
Now we have again a list of translated values. We "".join() it together again to get a new string: "BRR". We repeat the whole process until the string has a length of 1.

Function Calling Python basic

I'm trying to enter values from the tuple ('a',1), ('b',2),('c',3) into the function dostuff but i always get a return of None or False. i'm new to this to i'm sorry if this question is basic. I would appreciate any help.
I expect the result of this to be:
a1---8
b2---8
c3---8
Code:
def dostuff(stri,numb,char):
cal = stri+str(numb)+'---'+str(char)
return cal
def callit (tups,char):
for x in range(len(tups)):
dostuff(tups[x][0],tups[x][1],char)
print(callit([('a',1), ('b',2),('c',3)],8))
I think you're misunderstanding the return value of the functions: unless otherwise specified, all functions will return None at completion. Your code:
print(callit([('a',1), ('b',2),('c',3)],8))`
is telling the Python interpreter "print the return value of this function call." This isn't printing what you expect it to because the callit function doesn't have a return value specified. You could either change the return in your dostuff function like so:
def dostuff(stri,numb,char):
cal = stri+str(numb)+'---'+str(char)
print cal
def callit (tups,char):
for x in range(len(tups)):
dostuff(tups[x][0],tups[x][1],char)
callit([('a',1), ('b',2),('c',3)],8)
This changes the return on the third line into a print command, and removes the print command from the callit call.
Another option would be:
def dostuff(stri,numb,char):
cal = stri+str(numb)+'---'+str(char)
return cal
def callit (tups,char):
for x in range(len(tups)):
cal = dostuff(tups[x][0],tups[x][1],char)
print(cal)
callit([('a',1), ('b',2),('c',3)],8)
This takes the return value from the dostuff function and stores it in a variable named cal, which could then be printed or written to a file on disk.
as #n1c9 said, every Python function must return some object, and if there's no return statement written in the function definition the function will implicitly return the None object. (implicitly meaning that under the hood, Python will see that there's no return statement and returnNone)
However, while there's nothing wrong in this case with printing a value in a function rather than returning it, it's generally considered bad practice. This is because if you ever want to test the function to aid in debugging, you have to write the test within the function definition. While if you returned the value you could just test the return value of calling the function.
So when you're debugging this code you might write something like this:
def test_callit():
tups = [('a', 1), ('b', 2), ('c', 3)]
expected = 'a1---8\nb2---8\nc3---8'
result = callit(tups, 8)
assert result == expected, (str(result) + " != " + expected)
if you're unfamiliar with the assert statement, you can read up about it here
Now that you have a test function, you can go back and modify your code. Callit needs a return value, which in this case should probably be a string. so for the functioncallit you might write
def callit(tups, char):
result = ''
for x in range(len(tups)):
result += dostuff(tups[x][0], tups[x][1], char) + '\n'
result = result[:result.rfind('\n')] # trim off the last \n
return result
when you run test_callit, if you get any assertion errors you can see how it differs from what you expect in the traceback.
What I'm about to talk about isn't really relevant to your question, but I would say improves the readability of your code.
Python's for statement is very different from most other programming languages, because it actually acts like a foreach loop. Currently, the code ignores that feature and forces regular for-loop functionality. it's actually simpler and faster to write something like this:
def callit(tups, char):
result = ''
for tup in tups:
result += dostuff(tup[0], tup[1], char) + '\n'
result = result[:result.rfind('\n')] # trim off the last \n
return result
For a function to return a value in python it must have a return statement. In your callit function you lack a value to return. A more Pythonic approach would have both a value and iterate through the tuples using something like this:
def callit(tups, char):
x = [dostuff(a, b, char) for a, b in tups]
return x
Since tups is a list of tuples, we can iterate through it using for a, b in tups - this grabs both elements in the pairs. Next dostuff(a, b, char) is calling your dostuff function on each pair of elements and the char specified. Enclosing that in brackets makes the result a list, which we then return using the return statement.
Note you don't need to do:
x = ...
return x
You can just use return [dostuff(a, b, char) for a, b in tups] but I used the former for clarity.
You can use a list comprehension to do it in one line:
char = 8
point_list = [('a', 1), ('b', 2),('c', 3)]
print("\n".join(["{}{}---{}".format(s, n, char) for s, n in point_list]))
"{}{}---{}".format(s, n, char) creates a string by replacing {} by each one of the input in format, therefore "{}{}---{}".format("a", 1, 8) will return "a1---8"
for s, n in point_list will create an implicit loop over the point_list list and for each element of the list (each tuple) will store the first element in s and the second in n
["{}{}---{}".format(s, n, char) for s, n in point_list] is therefore a list created by applying the format we want to each of the tuples: it will return ["a1---8","b2---8","c3---8"]
finally "\n".join(["a1---8","b2---8","c3---8"]) creates a single string from a list of strings by concatenating each element of the list to "\n" to the next one: "a1---8\nb2---8\nc3---8" ("\n" is a special character representing the end of a line

Code not iterating over whole dictionary

so I have the following function:
def check(g,s):
for keys, value in g.items():
for w, val in enumerate(g[keys]):
print(s, g[keys][w], w)
if(s==g[keys][w]):
return 1
else:
return 0
g is a dictionary with an integer as a key and a list as a value
s is an integer I am looking for in the value lists
And I have the following data (a dictionary with an integer as the key and a list as a value):
d={1.4953487812212205: [1, 1.2228445449938519], 2.23606797749979: [2, 1.4953487812212205], 3.309750919646873: [3, 1.8192720851062585]}
The data is actually much longer but I reduced it for our simplicity.
That check function is looking for a specific value in the list of every key in the dictionary and return a 1 or 0. Now the problem is if I take the code and run it as a standalone (fixed dictionary and just run the check function), the code works fine (if I search 3, it will return a 1).
But if I integrate it to my larger code, the w variable never increments and it also only checks the first dictionary entry (only 1 key) instead of all of them and it never finds 3 (since it never gets there).
What can the problem be? I can't seem to put a finger on it.
Don't return 0 until you have checked all the values:
def check(g,s):
for keys, value in g.items():
for w, val in enumerate(g[keys]):
print(s, g[keys][w], w)
if(s==g[keys][w]):
return 1
return 0
Since you are iterating over items(), you don't have to re-lookup the values using the keys:
def check(g,s):
for keys, value in g.items():
for w, val in enumerate(value):
print(s, val, w)
if(s==val):
return 1
return 0
If you use any with a nested generator, you can accomplish the same thing (just look at the dict's values() collection, since you don't seem to care what the key is):
def check(g,s):
if any(s in vlist for vlist in g.values()):
return 1
else:
return 0
And since True = 1 and False = 0, this further reduces to:
def check(g,s):
return any(s in vlist for vlist in g.values())

how to return the iterations over keys as a string?

I am trying to return a string that contains the values of 2 attributes of every object in a dictionary and it's key . Every line is a key and the 2 attributes of it's object. The problem is that since the return statement ends the function, i only get the first key. I can get the results with print but i need the function to return the result.This is my attempted function:
aemptystring = ""
for key in self.cases.keys():
a = key, self.cases[key].color, self.cases[key].thetype
b = str(a) + "\n"
result = aemptystring + b
return result
and its gives me this:
"((3, 0), 'blanc', 'pion')\n"
It only does it for 1 key .The dictionary cases has number tuples as a key like (3,0) and the attributes of its object are .color which can be "noir" or "blanc" and .thetype is "pion" or "dame"
if i use print(aemptystring + b)i get the iterations for each key like i want which is like this:
((3, 0), 'blanc', 'pion')
((5, 4), 'blanc', 'pion')
((2, 1), 'noir', 'pion')
((1, 6), 'noir', 'pion')
....etc
How can i get the function to return the result of the iterations like the print gives me?
I can't just use print because i need to use the return of this function later on.The return also needs to be a string.
You could either append the results to a list and return the list of results outside the for loop, or you could use something called a generator which allows your function to resume executing where it left off after returning a value.
def generate_stuff():
for key in self.cases.keys():
a = key, self.cases[key].color, self.cases[key].thetype
yield str(a) + "\n"
for result in generate_stuff():
print result
Don't return inside the loop. :)
You almost got there with the aemptystring. You just have to keep adding onto it.
result = ""
for key in self.cases.keys():
a = key, self.cases[key].color, self.cases[key].thetype
b = str(a) + "\n"
result = result + b
return result
But concatenating strings repeatedly is quadratic, so it's better to build a list and then join it.
lines = []
for key in self.cases.keys():
a = key, self.cases[key].color, self.cases[key].thetype
lines.append(str(a) + "\n")
return ''.join(lines)
And you can make this a bit shorter with .items() and some string formatting.
lines = []
for key, case in self.cases.items():
a = key, case.color, case.thetype
lines.append("{0!r}\n".format(a))
return ''.join(lines)
It's a little weird to return a big string of Python reprs like this, though. Curious: what is this string used for?

Working with python dictionaries

I am writing a function that takes in an argument. From that argument, I want to compare it to a dictionary's set of keys and return the key's value for any matches. So far I have been able to only return the argument matches for the keys.
def func(str):
a = []
b = {'a':'b','c':'d','e':'f'}
for i in str:
if i in b.keys():
a.append(i)
return a
Output sample:
func('abcdefghiabcdefghi')
['a','c','e','a','c','e']
Wanted output:
['b','d','f','b','d','f']
Best not to use str as a variable name. I think your function can be written more simply like this
def func(mystr):
b = {'a':'b','c':'d','e':'f'}
return [b[k] for k in mystr if k in b]
If you don't want to use a list comprehension, then you can fix it like this
def func(mystr):
a = []
b = {'a':'b','c':'d','e':'f'}
for i in mystr:
if i in b: # i in b works the same as i in b.keys()
a.append(b[i]) # look up the key(i) in the dictionary(b) here
return a

Categories

Resources