Enumerate list using recursion, python - python

I'm trying to enumerate the list using recursion and am having a hard time doing so.
If anyone can point me in the right direction that would be greatly appreciated! :)
def my_enumerate(items, start_index=0):
"""my enumerate"""
result = []
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
my_enumerate(items[1:], start_index + 1)
return result
ans = my_enumerate([10, 20, 30])
print(ans)**strong text**

Try:
def my_enumerate(items, start_index=0):
"""my enumerate"""
result = []
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
result += my_enumerate(items[1:], start_index + 1) # here
return result
The following is more concise:
def my_enumerate(items, start_index=0):
"""my enumerate"""
return [(start_index, items[0])] + my_enumerate(items[1:], start_index + 1) if items else []

As you are using recursion and you are declaring result = [] within a function so everytime it simply gets empty so you lose all previous results.
If you want exactly this to work there is also another way that by making the result as global if you wanted to use that list globally like below:
result = []
def my_enumerate(items, start_index=0):
"""my enumerate"""
global result
if not items:
return []
else:
a = (start_index, items[0])
result.append(a)
my_enumerate(items[1:], start_index + 1)
return result
ans = my_enumerate([10, 20, 30])
print(and)
But #CocompleteHippopotamus answer will work when you don't want to use a global keyword.

Related

Cannot Make Sense of How Local and Global Variable Work

As a new python learner, I really appreciate your advice why my understanding about the following case is wrong:
When I wrote code as follows:
class Solution(object):
def isHappy(self, n):
seen = {}
while n!=1 and n not in seen.keys():
seen[n] = '*'
n = self.get_next(n)
return n==1
total_sum = 0
def get_next(self,no):
while no>0:
no,v = divmod(no,10)
total_sum+=v**2
return total_sum
test55 = Solution()
test55.isHappy(56)
But it throws me the error saying "local variable 'total_sum' referenced before assignment", I think it should work because: although we didn't initialize total_sum inside get_next function, I expect it should look for total_sum outside of the function. Could anyone share some advice why I'm wrong?
If we put total_sum inside get_next function, then it works:
class Solution(object):
def isHappy(self, n):
seen = {}
while n!=1 and n not in seen.keys():
seen[n] = '*'
n = self.get_next(n)
return n==1
def get_next(self,no):
total_sum = 0
while no>0:
no,v = divmod(no,10)
total_sum+=v**2
return total_sum
test55 = Solution()
test55.isHappy(56)

Nested Lists- Python

I need to write the body of a Python method that does the following:
1)takes a list, where list[0] is a string and list[1] is either a list which looks the same or None
2)print every string of the list
I have to use the while loop and not use list comprehension or flatten.
def pick_cherries_iter(field):
""""e.g.
>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!', None]]]]]
>>> pick_cherries_iter(cherry_field)
cherry1
cherry2
cherry3
cherry4
Yay!!!"""
_______________________
_______________________
_______________________
_______________________
while _________________:
_______________________
_______________________
_______________________
I know that for the example above I can print cheery1 if I print cherry_field[0] or cherry1 for cherry_field[1][0] or cherry2 for cherry_filed[1][1][0] etc, however I am not sure how to go through these elements using the while loop.
I think this should work for you. Please check it.
Using While Loop:
def pick_cherry(field):
""""e.g.
>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!',None]]]]]
>>> pick_cherry(cherry_field)
cherry1
cherry2
cherry3
cherry4
Yay!!!"""
while field[1] != None:
temp = field[0]
print temp
field = field[1]
print field[0]
Using Flatten(and Recursion):
flatten_field = []
def pick_cherry(field):
if field[1] != None:
flatten_field.append(field[0])
pick_cherry(field[1])
else:
flatten_field.append(field[0])
def flatten_func(field):
""""e.g.
>>> cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!',None]]]]]
>>> flatten_func(cherry_field)
cherry1
cherry2
cherry3
cherry4
Yay!!!"""
pick_cherry(field)
for item in flatten_field:
print item
I would do this recursively because you have no way of knowing if an element is a list or not.
#!/usr/bin/python -E
cherry_field = ['cherry1', ['cherry2', ['cherry3', ['cherry4', ['Yay!!!', None]]]]]
def print_list(field):
i = 0
list_length = len(field)
while i < list_length:
if field[i] is not None and type(field[i]) is not list:
print(field[i])
else:
if field[i] is not None:
print_list(field[i])
i += 1
if i < list_length and type(field[i]) is list:
print_list(field[i])
i += 1
def pick_cherries(field):
if type(field) is list:
print_list(field)
pick_cherries(cherry_field)

Referencing python variable inside functions

I have the following python code to delete all the copies of a file in a certain directory keeping only one of them.
It works fine if i comment out the first four lines in the delete() function but if i don't it gives me a error that local variable list1 referenced before assignment. Also I tried using something called global but it didn't help me much as it gave error saying that it is NoneType.
Please help me i am just a intermediate beginner in Python.
list1 = []
list2 = []
def stripe(lis):
for i in range(len(lis)):
lis[0] = lis[0].strip()
def scan(pat):
pat = os.path.abspath(pat)
files = os.listdir(pat)
for file in files:
filepath = os.path.join(pat,file)
if os.path.isfile(filepath):
list1.append(file)
list2.append('{0}'.format(filepath))
elif os.path.isdir(filepath):
scan(filepath)
def delete():
list1_1 = stripe(list1)
list2_1 = stripe(list2)
list1 = list1_1
list2 = list2_1
length = len(list1)
#length = length - 1
i = 0
while i < length:
item = list1[0]
a = list1[0]
b = list2[0]
del list1[0]
del list2[0]
if item in list1:
try:
os.remove(list2[list1.index(item)])
#del list1[list1.index(item)]
#del list2[list1.index(item)]
except:
print('sorry',list1[0],'could not be deleted',sep = ' ')
print('wow')
i += 1
#list1.append(a)
#list2.append(b)
global looks like the right option for you, but if you say it gives error, use the way that comes to mind first. list1 and list2 can be the parameters of the delete() function.
Something like this:
def delete(list1, list2):
...
def foo():
list1 = []
list2 = []
...
delete(list1, list2)
Also, as I said, global is always an option. Here is an easy example:
list = []
def foo():
global list
list.append(1234)
def foo2():
global list
print(list)
foo()
foo2()
Output:
[1234]

Why does passing a dictionary as a parameter take more time?

I tried to a leetcode problem. I find one of the following code throws a time limit exceeded error. I created the following testing code. I found the first one pass dictionary as a parameter takes more time the the other one. 0.94s vs 0.84s.
Can anyone explain this ?
class Solution(object):
def longestPalindromeSubseq(self, x):
"""
:type s: str
:rtype: int
"""
#dic = {}
def helper(s, dic):
if len(s) == 0:
return 0
if len(s) == 1:
return 1
if s in dic:
return dic[s]
if s[0] == s[-1]:
res = helper(s[1:-1], dic)+2
else:
l1 = helper(s[:-1], dic)
l2 = helper(s[1:], dic)
res = max(l1,l2)
dic[s] = res
#print (id(dic), dic)
return res
d = {}
ans = helper(x, d)
#print (id(d), d)
return ans
class Solution1(object):
def longestPalindromeSubseq(self, x):
"""
:type s: str
:rtype: int
"""
dic = {}
def helper(s):
if len(s) == 0:
return 0
if len(s) == 1:
return 1
if s in dic:
return dic[s]
if s[0] == s[-1]:
res = helper(s[1:-1])+2
else:
l1 = helper(s[:-1])
l2 = helper(s[1:])
res = max(l1,l2)
dic[s] = res
#print (id(dic), dic)
return res
ans = helper(x)
#print (id(dic), dic)
return ans
import time
if __name__ == "__main__":
x = "gphyvqruxjmwhonjjrgumxjhfyupajxbjgthzdvrdqmdouuukeaxhjumkmmhdglqrrohydrmbvtuwstgkobyzjjtdtjroqpyusfsbjlusekghtfbdctvgmqzeybnwzlhdnhwzptgkzmujfldoiejmvxnorvbiubfflygrkedyirienybosqzrkbpcfidvkkafftgzwrcitqizelhfsruwmtrgaocjcyxdkovtdennrkmxwpdsxpxuarhgusizmwakrmhdwcgvfljhzcskclgrvvbrkesojyhofwqiwhiupujmkcvlywjtmbncurxxmpdskupyvvweuhbsnanzfioirecfxvmgcpwrpmbhmkdtckhvbxnsbcifhqwjjczfokovpqyjmbywtpaqcfjowxnmtirdsfeujyogbzjnjcmqyzciwjqxxgrxblvqbutqittroqadqlsdzihngpfpjovbkpeveidjpfjktavvwurqrgqdomiibfgqxwybcyovysydxyyymmiuwovnevzsjisdwgkcbsookbarezbhnwyqthcvzyodbcwjptvigcphawzxouixhbpezzirbhvomqhxkfdbokblqmrhhioyqubpyqhjrnwhjxsrodtblqxkhezubprqftrqcyrzwywqrgockioqdmzuqjkpmsyohtlcnesbgzqhkalwixfcgyeqdzhnnlzawrdgskurcxfbekbspupbduxqxjeczpmdvssikbivjhinaopbabrmvscthvoqqbkgekcgyrelxkwoawpbrcbszelnxlyikbulgmlwyffurimlfxurjsbzgddxbgqpcdsuutfiivjbyqzhprdqhahpgenjkbiukurvdwapuewrbehczrtswubthodv"
print (x)
t0 = time.time()
sol = Solution()
print (sol.longestPalindromeSubseq(x))
t1 = time.time()
print(t1- t0)
sol1 = Solution1()
print (sol1.longestPalindromeSubseq(x))
t2 = time.time()
print(t2-t1)
Python uses something that is called call by sharing. The function gets only the alias on the parameter. With that in mind, it does't matter what you pass to the function.
But the script may take different time to execute. It is not constant. Using recursion makes it even harder to predict

print a binary tree how to fix the build_balanced_bst function

def str_tree(atree,indent_char ='.',indent_delta=2):
def str_tree_1(indent,atree):
if atree == None:
return ''
else:
answer = ''
answer += str_tree_1(indent+indent_delta,atree.right)
answer += indent*indent_char+str(atree.value)+'\n'
answer += str_tree_1(indent+indent_delta,atree.left)
return answer
return str_tree_1(0,atree)
def build_balanced_bst(l):
if len(l) == 0:
return None
else:
mid = (len(l)-1)/2
if mid >= 1:
build_balanced_bst(l[:mid])
build_balanced_bst(l[mid:])
else:
return
I am working on the build_balanced_bst(l), the build_balanced_bst(l) takes a list of unique values that are sorted in increasing order. calling build_ballanced_bst( list(irange(1,10)) returns a binary search tree of height 3 that would print as:
......10
....9
..8
......7
....6
5
......4
....3
..2
....1
the str_tree function is used to print what the build_balanced_bst() function returns. my str_tree function is correct, I cannot change it. I can only change the build_balanced_bst() function.
I used the middle value in the list as the root’s value. when I try to call the build_balanced_bst(l) in the below, it does not print anything.
l = list(irange(1,10))
t = build_balanced_bst(l)
print('Tree is\n',str_tree(t),sep='')
can someone help me to fix my build_balanced_bst(l) function? many thanks.
str_tree() doesn't do anything: It just defines a nested function and implicitly returns None.
As a start, you can have str_tree do something:
def str_tree(atree, indent_char ='.', indent_delta=2):
def str_tree_1(indent, atree):
# Note that str_tree_1 doesn't use the indent argument
if atree == None:
return ''
return str_tree_1(indent_delta, atree)
But this is just a start.

Categories

Resources