I am having trouble understanding lists:
mList = []
def func1(mList):
mList.append("1")
return
func1()
print mList
As I understand it because a list is mutable, if I edit it in a function, the main list will also be edited. In a program I am working on this is happening with one list which I am using as a "save file", however, a second list which I am using as a "value_blacklist" is not being saved after it is edited/added to.
I included the problem part of the actual code I am having issues with if it's of any help.
def func04(feedback, test_list, value_blacklist, upper_limit=6):
if value_blacklist == []:
value_blacklist = blacklist_gen(length)
import random
new_list = []
for index in list(range(0, len(feedback))):
if feedback[index] == 0: #This value is correct, leave it
new_list.append(test_list[index])
elif feedback[index] == 2:
value_blacklist = full_blacklist(test_list[index], value_blacklist)
new_list.append(0)
elif feedback[index] == 1:
value_blacklist[index].append(test_list[index])
new_list.append(0)
for index in list(range(0, len(feedback))):
if new_list[index] == 0:
new_list[index] = pick_new(index, value_blacklist, upper_limit)
return new_list
next_guess = lambda: func04(feedback(), save_game[-1], value_blacklist, save_game[0])
Thanks for any help, I'm really confused by this.
Whereever you are saying
value_blacklist = ...
You are rebinding value_blacklist to a new (list) object. If you instead say
value_blacklist[:] = ...
You will replace the contents of the list without rebinding it.
Ask lots of questions until you really really understand this. It's very important to "get" it.
When you use = operator in a function, you are not modifying the existing object. Right hand side of the expression creates a new list and returns a reference to it and that reference is assigned to value_blacklist.
value_blacklist = blacklist_gen(length)
...
value_blacklist = full_blacklist(test_list[index], value_blacklist)
These are the places where you create new local lists and referring them with value_blacklist. That's why value_blacklist doesn't reflect the changes. You can confirm this by printing the id of value_blacklist after the assignment statements and at the beginning of the function.
Related
i have a function to append a list, something like this:
def append_func(element):
if xxxx:
new_list.append(element)
else:
[]
I have another function that uses append_func():
def second_func(item):
for i in item:
append_func(i)
if i run :
new_list = []
second _func(item)
new_list
This will return the list i want, but i can't do new_list = second _func(item) because in this case new_list will be a None.
I understand that append() will return a None type, but i'd like to return the appended list so I can use in other places result = second _func(xxx), what i have missed? Thanks.
According to the clarification you did in the comments you might want something like this. (I changed some of your placeholders so we have running code and a reproducible example)
The list is created by second_func so we get rid of the global list.
def append_func(data, element):
if 2 < element < 7:
data.append(element ** 2)
def second_func(items):
new_list = []
for i in items:
append_func(new_list, i)
return new_list
items = list(range(10))
result = second_func(items)
print(result)
The result is [9, 16, 25, 36].
simply tell python what to return:
def append_func(element):
if xxxx:
new_list.append(element)
else:
[]
return new_list # here, return whatever you want to return
if there is no "return" statement in the function, then the function returns None
The new_list you define before calling second_func is a global variable. Every time you call second_func() it will append the argument to the global variable. But the new_list is not restricted to the namespace of either function, so setting it as a return value doesn't make sense.
I'm attempting to generate all n choose k combinations of a list (not checking for uniqueness) recursively by following the strategy of either include or not include an element for each recursive call. I can definitely print out the combinations but I for the life of me cannot figure out how to return the correct list in Python. Here are some attempts below:
class getCombinationsClass:
def __init__(self,array,k):
#initialize empty array
self.new_array = []
for i in xrange(k):
self.new_array.append(0)
self.final = []
self.combinationUtil(array,0,self.new_array,0,k)
def combinationUtil(self,array,array_index,current_combo, current_combo_index,k):
if current_combo_index == k:
self.final.append(current_combo)
return
if array_index >= len(array):
return
current_combo[current_combo_index] = array[array_index]
#if current item included
self.combinationUtil(array,array_index+1,current_combo,current_combo_index+1,k)
#if current item not included
self.combinationUtil(array,array_index+1,current_combo,current_combo_index,k)
In the above example I tried to append the result to an external list which didn't seem to work. I also tried implementing this by recursively constructing a list which is finally returned:
def getCombinations(array,k):
#initialize empty array
new_array = []
for i in xrange(k):
new_array.append(0)
return getCombinationsUtil(array,0,new_array,0,k)
def getCombinationsUtil(array,array_index,current_combo, current_combo_index,k):
if current_combo_index == k:
return [current_combo]
if array_index >= len(array):
return []
current_combo[current_combo_index] = array[array_index]
#if current item included & not included
return getCombinationsUtil(array,array_index+1,current_combo,current_combo_index+1,k) + getCombinationsUtil(array,array_index+1,current_combo,current_combo_index,k)
When I tested this out for the list [1,2,3] and k = 2, for both implementations, I kept getting back the result [[3,3],[3,3],[3,3]]. However, if I actually print out the 'current_combo' variable within the inner (current_combo_index == k) if statement, the correct combinations print out. What gives? I am misunderstanding something to do with variable scope or Python lists?
The second method goes wrong because the line
return [current_combo]
returns a reference to current_combo. At the end of the program, all the combinations returned are references to the same current_combo.
You can fix this by making a copy of the current_combo by changing the line to:
return [current_combo[:]]
The first method fails for the same reason, you need to change:
self.final.append(current_combo)
to
self.final.append(current_combo[:])
Check this out: itertools.combinations. You can take a look at the implementation as well.
I have this:
def ppend(n):
lis = []
if n.rest == None:
pass
else:
lis.append(n.first)
ppend(n.rest)
return lis
n is a linked-list [1,2,3]
The output I am getting is :
[1]
But the output I am looking for is:
[1,2,3]
You are creating a new lis list on every recursion. (Incidentally, you might try to find more descriptive names.) Only the first list is returned, however, because you don't do anything with the other lists that result from recursion. Instead, you simply call the function, which simply creates a new list without doing anything with the value returned by the function. You can see this in the following line:
ppend(n.rest) # a new list is created but nothing is done with the result of the function
If you only plan to use the function once, you can simply move the lis assignment outside of the function:
lis = []
def ppend(n):
if n.rest is not None: # the first if statement appears unnecessary
lis.append(n.first)
ppend(n.rest)
return lis # or don't return it but simply refer to lis where you need to
The above approach, however, will not work as well if you plan to use the function multiple times and always need a new list. In the latter case, you might add a second function like this:
def make_ppend(n, lis): # add lis as a parameter to be explicit, but you could rely on scope instead of adding this extra parameter
if n.rest is not None:
lis.append(n.first)
make_ppend(n.rest, lis)
def ppend(n):
lis = [] # now in the local scope
make_ppend(n, lis)
return lis
I am guessing you are after something like the second solution.
I want every element in l(which is a list) to be added to a.
When I run the function, it gives me '[]' every time. How can I fix this?
def sim(l):
a = []
if len(l)>0:
a = a.append(l.pop())
l.pop()
return sim(l)
return a
Several things are wrong:
You shouldn't use lowercase L for a variable name - it looks like one
At the top of the function you assign an empty list to a - ultimately sim will be called with an empty list, then a will be assigned an empty list, the conditional statement will fail and sim will return an empty list.
Inside the conditional statement you assign the return value of list.append() to a. The return value is None so whatever a was before, it gets wiped out.
Inside the conditional statement you pop() two items out of your control list
An empty list has a boolean value of false so there is no need to explicitly check its length,
def sim(el, a = None):
if el:
a.append(el.pop())
return sim(el, a)
return a
I was taught to write the base case of a recursive function as the first statement:
def sim(el, a = None):
if not el:
return a
a.append(el.pop())
return sim(el, a)
append() doesn't return anything but does update the existing list. In other words, by trying to assign the result of the append() method, you're setting a to nothing after you have already appended the item.
Your Code :def sim(l):
a = []
when you call Function recursively return sim(l) every time it is call sim(l) and a=[] is empty.
Try This :
def sim(l,a):
if len(l)>0:
a.append(l.pop())
print a
return sim(l,a)
return a
Is this a homework assignment where you're required to do it in a certain (overly complicated) way? Because if not, you can add one list to another in Python like so:
>>> l = [1, 2, 3]
>>> a = []
>>> a.extend(l)
>>> a
[1, 2, 3]
I am trying to run a sorting function recursively in python. I have an empty list that starts everything but everytime I try to print the list I get an empty list. here is my code. Any help would be greatly appreciated
def parse(list):
newParse = []
if len(list) == 0:
return newParse
else:
x = min(list)
list.remove(x)
newParse.append(x)
return sort(list)
The value of newParse is not preserved between invocations of the function; you're setting it equal to [] (well, you're creating a new variable with the value []).
Since the only time you return is
newParse = []
if len(list) == 0:
return newParse`
you will always be returning [] because that is the value of newParse at that time.
Because you are doing this recursively, you are calling the function anew, without keeping the function's own state. Take a moment to consider the implications of this on your code.
Instead of initialising newParse = [], add an optional parameter newParse defaulting to a bogus value, and set newParse = [] if you receive that bogus value for newParse. Otherwise, you'll actually be getting the same list every time (i.e. the contents of the list object are being mutated). And newParse through in your tail call.
You also seem to have the problem that your definition and and the supposedly-recursive call refer to different functions.
def sort(list, newParse = None):
if newParse is None:
newParse = []
if len(list) == 0:
return newParse
else:
x = min(list)
list.remove(x)
newParse.append(x)
return sort(list, newParse)
Here is what I think you are trying to do:
def recursive_sort(a_list):
def helper_function(list_to_be_sorted, list_already_sorted):
new = []
if len(list_to_be_sorted) == 0:
return list_already_sorted
else:
x = min(list_to_be_sorted)
list_to_be_sorted.remove(x)
new.append(x)
return helper_function(list_to_be_sorted, list_already_sorted + new)
return helper_function(a_list, [])
You shouldn't name variables list, as that is a builtin.
Also, if you are trying to implement a recursive sort function, you might want to look at quicksort, which is a very common (and fast) recursive sorting algorithm. What you have tried to implement is a recursive version of selection sort, which is much slower.
Also, if you actually need a sorting function, rather than just wanting to implement a recursive one, you should use the list method sort, or the function on an iterable sorted, both of which will be a lot faster than anything you could make in Python.