recursion global variable return - python

In a certain condition I want to count up and return that value
but when I use recursion it reset the value
so I tried to use global variable
but it said
NameError: name 'count' is not defined
Here is my recursion code
def solution(relation):
global count
df = pd.DataFrame(relation)
for i in range(len(relation[0])):
for j in range(len(relation[0])):
if j != i:
temp = df[i] + df[j]
else:
temp = df[j]
if(len(temp)==len(set(temp))):
count +=1
for jj in range(len(relation)):
relation[jj] = relation[jj][1:]
return solution(relation)
return count

You must declare count also outside of function. Like this :
count = 0
def my_function(relation)
global count
# code here

Instead of using as global variable pass it to the recursion and then update it
By calling with updated count
for E.g
def solution(relation, count=0):
""" Your code logic"""
solution(relation, count=count)

If you really want to use it as a global variable, define it outside the function and it will work.
count = 0
def solution(relation):
df = pd.DataFrame(relation)
for i in range(len(relation[0])):
for j in range(len(relation[0])):
if j != i:
temp = df[i] + df[j]
else:
temp = df[j]
if(len(temp)==len(set(temp))):
count +=1
for jj in range(len(relation)):
relation[jj] = relation[jj][1:]
return solution(relation)
return count
But this is a bad practice since it will expose an internal variable to outside unnecessarily. So the best way is passing it as an argument as mentioned in the other solution.

Related

Adding to a Python Dictionary

def countFrequency(L):
fdict = {}
for x in range(0, len(L)):
for key, value in fdict:
if L[x] == fdict[str(x)]:
value = value + 1
else:
fdict[L[x]] = 1
return fdict
I'm trying to count the frequency of occurrences of a particular symbol in a given string and create a dictionary out of this. For some reason, the function just returns an empty dictionary. I think the problem arises with adding a new value to the dictionary, but not sure how to troubleshoot it/fix it.
input: countFrequency('MISSISSIPPI')
output: {}
Do this:
def countFrequency(L):
fdict = {}
for x in range(0, len(L)):
if str(L[x]) in fdict.keys():
fdict[str(L[x])] = fdict[str(L[x])] + 1
else:
fdict[str(L[x])] = 1
return fdict
The code in the inner loop:
if L[x] == fdict[str(x)]:
value = value + 1
else:
fdict[L[x]] = 1
is unreachable, because the dictionary is empty initally, and hence you will never add any value to fdict.
you can do it likes this:
def countFrequency(L):
fdict = {}
for symbol in L: #gets each letter in l
if symbol in fdict: #check if dhe dictionary already has an value for the symbol
fdict[symbol] += 1
else:
fdict[symbol] = 1
return fdic
Another issue is that the value value is never assigned to anything or used, so even if we were to go through the loop we would never increment a value in the dictionary.

Append element to a list inside nested list - python

I am developing a procedure add_to_index, that takes 3 inputs:
an index: [[,[url1,url2,...]],...]
a keyword: String
a url: String
If the keyword is already in the index, url is added to the list of urls associated with that keyword.
If the keyword is not in the index, a new element is to the index:
[keyword,[url]]
CODE
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
count += 1
if(lists[0]==keyword):
index[count][1].append(url)
if(flag ==0):
index.append([keyword,url])
#calling the function below
add_to_index(index,'google','http://google.com')
print index
output -> [['google', 'http://google.com']]
add_to_index(index,'computing','http://acm.org')
print index
output -> [['google', 'http://google.com'], ['computing', 'http://acm.org']]
add_to_index(index,'google','http://gmail.com')
print index
error->
index[count][1].append(url)
AttributeError: 'str' object has no attribute 'append'
Expected output:
[['google', ['http://google.com', 'http://gmail.com']],
['computing', ['http://acm.org']]]
You have done three mistakes, Firstly you have not used the flag and secondly you are adding the url as a string. And finally as Kaivosuketaja has mentioned in the comment, count should be incremented in the end. It can be done otherwise as
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
if(lists[0]==keyword):
flag = 1
index[count][1].append(url)
count += 1
if(flag ==0):
index.append([keyword,[url]])
# Take note of append away here
#calling the function below
add_to_index(index,'google','http://google.com')
print index
add_to_index(index,'computing','http://acm.org')
print index
add_to_index(index,'google','http://gmail.com')
print index
The output now is
[['google', ['http://google.com']]]
[['google', ['http://google.com']], ['computing', ['http://acm.org']]]
[['google', ['http://google.com', 'http://gmail.com']], ['computing', ['http://acm.org']]]
I think this is what you want:
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
if lists[0] == keyword:
lists[1].append(url)
flag = 1
count += 1
if flag == 0:
index.append([keyword, [url]])
#calling the function below
add_to_index(index,'google','http://google.com')
print index
I will suggest the use of dictionaries for this:
index = {}
def add_to_index(index, keyword, url):
if keyword not in index:
index[keyword] = [url]
else:
index[keyword].append(url)
>>> add_to_index(index,'computing','http://acm.org')
>>> add_to_index(index,'google','http://gmail.com')
>>> add_to_index(index,'google','http://gmail.com')
>>> index
{'computing': ['http://acm.org'], 'google': ['http://gmail.com', 'http://gmail.com']}
You could even make index a non global variable by implementing a simple class(ofcourse, this is possible with nested lists too):
class Index(object):
def __init__(self):
self.index = {}
def add_to_index(self, keyword, url):
if keyword not in index:
self.index[keyword] = [url]
else:
self.index[keyword].append(url)
First, you're trying to append to a string that is inside of the list you want to append to. Then, you forgot to say flag = 1 when you've found the keyword. Try the following:
index = []
def add_to_index(index,keyword,url):
flag = 0
count = 0
for lists in index:
if(lists[0]==keyword):
index[count][1].append(url)
flag = 1
count += 1
if(flag ==0):
index.append([keyword,url])
#calling the function below
add_to_index(index,'google','http://google.com')
add_to_index(index,'computing','http://acm.org')
add_to_index(index,'google','http://gmail.com')
print index
I think you'd be much better off using a defaultdict, though. It automatically searches for a keyword and adds the item to the existing keyword, or if it isn't found, creates a new keyword.
You could simplify things a little by getting rid of the flag and count variables.
index = []
def add_to_index(index, keyword, url):
for e in index:
if e[0] == keyword:
e[1].append(url)
return
else:
index.append([keyword,[url]])

making a function that takes a list as input and return count of the string “bebo” in that list

I want a function called bebo_count that takes a list x as input and returns the count of the string “bebo” in that list.
For example, bebo_count(["bebo","buzz","bebo"]) should return 2
i have made a code like this
def bebo_count(x):
for a in x:
count = 0
if a == "bebo":
count += 1
return count
but it doesn't work it's always return 1 to me,can any one please modify this code to be working well?!
You keep resetting count = 0 in your loop, move it outside:
def bebo_count(x):
count = 0
for a in x:
if a == "bebo":
count += 1
return count
do not reinvent the wheel :-)
There is a built in method count
x = [ "bebo", "bv", "bebo" ]
x.count("bebo")
> 2
x.count("b")
> 0
You are setting count = 0 inside the for loop. That means that at each loop iteration, irrespective of what the value of count was before, it gets set back to zero. You should initialize count outside the loop. Note also that I have corrected your indentation.
def bebo_count(x):
count = 0
for a in x:
if a == "bebo":
count += 1
return count
For your reference, here is another way you might write this same function:
def bebo_count(x):
return len([a for a in x if a == "bebo"])
Your problem is: count = 0 is inside your for loop.
To fix your code :
def bebo_count(x):
count = 0 # initialize the count before you start counting
for a in x:
if a == "bebo":
count += 1
return count
However, a more pythonic way could be using list comprehension:
big_list = ["bebo", "something else", "bebo"]
def bebo_count(big_list) :
return len( [x for x in big_list if x=="bebo" ] )
print( bebo_count(big_list))

how to change the value of a variable inside an if loop each time the if loop is triggered ?

i am trying to use codeacademy to learn python. the assignment is to "Write a function called fizz_count that takes a list x as input and returns the count of the string “fizz” in that list."
# Write your function below!
def fizz_count(input):
x = [input]
count = 0
if x =="fizz":
count = count + 1
return count
i think the code above the if loop is fine since the error message ("Your function fails on fizz_count([u'fizz', 0, 0]); it returns None when it should return 1.") only appears when i add that code.
i also tried to make a new variable (new_count) and set that to count + 1 but that gives me the same error message
I would appreciate your assistance very much
The problem is that you have no loop.
# Write your function below!
def fizz_count(input):
count = 0
for x in input: # you need to iterate through the input list
if x =="fizz":
count = count + 1
return count
There is a more concise way by using the .count() function:
def fizz_count(input):
return input.count("fizz")
Get rid of x = [input], that just creates another list containing the list input.
i think the code above the if loop is fine
ifs don't loop; you're probably looking for for:
for x in input: # 'x' will get assigned to each element of 'input'
...
Within this loop, you would check if x is equal to "fizz" and increment the count accordingly (as you are doing with your if-statement currently).
Lastly, move your return-statement out of the loop / if-statement. You want that to get executed after the loop, since you always want to traverse the list entirely before returning.
As a side note, you shouldn't use the name input, as that's already assigned to a built-in function.
Putting it all together:
def fizz_count(l):
count = 0 # set our initial count to 0
for x in l: # for each element x of the list l
if x == "fizz": # check if x equals "fizz"
count = count + 1 # if so, increment count
return count # return how many "fizz"s we counted
def fizz_count(x): #DEFine func
count = 0 #set counter to zero
for item in x:
if item == "fizz" :
count += 1 #iterate counter +1 for each match
print count #print result
return count #return value
fizz_count(["fizz","buzz","fizz"]) #call func
Try this:
# Write your function below!
def fizz_count(x):
count = 0
for item in x:
if item == "fizz":
count = count + 1
return count
def fizz_count(input)
count = 0
for x in input:
count += 1 if x=="fizz" else 0
return count

Python Dynamic Knapsack

Right now I am attempting to code the knapsack problem in Python 3.2. I am trying to do this dynamically with a matrix. The algorithm that I am trying to use is as follows
Implements the memoryfunction method for the knapsack problem
Input: A nonnegative integer i indicating the number of the first
items being considered and a nonnegative integer j indicating the knapsack's capacity
Output: The value of an optimal feasible subset of the first i items
Note: Uses as global variables input arrays Weights[1..n], Values[1...n]
and table V[0...n, 0...W] whose entries are initialized with -1's except for
row 0 and column 0 initialized with 0's
if V[i, j] < 0
if j < Weights[i]
value <-- MFKnapsack(i - 1, j)
else
value <-- max(MFKnapsack(i -1, j),
Values[i] + MFKnapsack(i -1, j - Weights[i]))
V[i, j} <-- value
return V[i, j]
If you run the code below that I have you can see that it tries to insert the weight into the the list. Since this is using the recursion I am having a hard time spotting the problem. Also I get the error: can not add an integer with a list using the '+'. I have the matrix initialized to start with all 0's for the first row and first column everything else is initialized to -1. Any help will be much appreciated.
#Knapsack Problem
def knapsack(weight,value,capacity):
weight.insert(0,0)
value.insert(0,0)
print("Weights: ",weight)
print("Values: ",value)
capacityJ = capacity+1
## ------ initialize matrix F ---- ##
dimension = len(weight)+1
F = [[-1]*capacityJ]*dimension
#first column zeroed
for i in range(dimension):
F[i][0] = 0
#first row zeroed
F[0] = [0]*capacityJ
#-------------------------------- ##
d_index = dimension-2
print(matrixFormat(F))
return recKnap(F,weight,value,d_index,capacity)
def recKnap(matrix, weight,value,index, capacity):
print("index:",index,"capacity:",capacity)
if matrix[index][capacity] < 0:
if capacity < weight[index]:
value = recKnap(matrix,weight,value,index-1,capacity)
else:
value = max(recKnap(matrix,weight,value,index-1,capacity),
value[index] +
recKnap(matrix,weight,value,index-1,capacity-(weight[index]))
matrix[index][capacity] = value
print("matrix:",matrix)
return matrix[index][capacity]
def matrixFormat(*doubleLst):
matrix = str(list(doubleLst)[0])
length = len(matrix)-1
temp = '|'
currChar = ''
nextChar = ''
i = 0
while i < length:
if matrix[i] == ']':
temp = temp + '|\n|'
#double digit
elif matrix[i].isdigit() and matrix[i+1].isdigit():
temp = temp + (matrix[i]+matrix[i+1]).center(4)
i = i+2
continue
#negative double digit
elif matrix[i] == '-' and matrix[i+1].isdigit() and matrix[i+2].isdigit():
temp = temp + (matrix[i]+matrix[i+1]+matrix[i+2]).center(4)
i = i + 2
continue
#negative single digit
elif matrix[i] == '-' and matrix[i+1].isdigit():
temp = temp + (matrix[i]+matrix[i+1]).center(4)
i = i + 2
continue
elif matrix[i].isdigit():
temp = temp + matrix[i].center(4)
#updates next round
currChar = matrix[i]
nextChar = matrix[i+1]
i = i + 1
return temp[:-1]
def main():
print("Knapsack Program")
#num = input("Enter the weights you have for objects you would like to have:")
#weightlst = []
#valuelst = []
## for i in range(int(num)):
## value , weight = eval(input("What is the " + str(i) + " object value, weight you wish to put in the knapsack? ex. 2,3: "))
## weightlst.append(weight)
## valuelst.append(value)
weightLst = [2,1,3,2]
valueLst = [12,10,20,15]
capacity = 5
value = knapsack(weightLst,valueLst,5)
print("\n Max Matrix")
print(matrixFormat(value))
main()
F = [[-1]*capacityJ]*dimension
does not properly initialize the matrix. [-1]*capacityJ is fine, but [...]*dimension creates dimension references to the exact same list. So modifying one list modifies them all.
Try instead
F = [[-1]*capacityJ for _ in range(dimension)]
This is a common Python pitfall. See this post for more explanation.
for the purpose of cache illustration, I generally use a default dict as follows:
from collections import defaultdict
CS = defaultdict(lambda: defaultdict(int)) #if i want to make default vals as 0
###or
CACHE_1 = defaultdict(lambda: defaultdict(lambda: int(-1))) #if i want to make default vals as -1 (or something else)
This keeps me from making the 2d arrays in python on the fly...
To see an answer to z1knapsack using this approach:
http://ideone.com/fUKZmq
def zeroes(n,m):
v=[['-' for i in range(0,n)]for j in range(0,m)]
return v
value=[0,12,10,20,15]
w=[0,2,1,3,2]
v=zeroes(6,5)
def knap(i,j):
global v
if i==0 or j==0:
v[i][j]= 0
elif j<w[i] :
v[i][j]=knap(i-1,j)
else:
v[i][j]=max(knap(i-1,j),value[i]+knap(i-1,j-w[i]))
return v[i][j]
x=knap(4,5)
print (x)
for i in range (0,len(v)):
for j in range(0,len(v[0])):
print(v[i][j],end="\t\t")
print()
print()
#now these calls are for filling all the boxes in the matrix as in the above call only few v[i][j]were called and returned
knap(4,1)
knap(4,2)
knap(4,3)
knap(4,4)
for i in range (0,len(v)):
for j in range(0,len(v[0])):
print(v[i][j],end="\t\t")
print()
print()

Categories

Resources