I want to loop through the original entries of a list even though it gets updated.
itterable = copy.deepcopy(dict[node].adjacent_nodes)
for i in itterable:
new_node = create_node(i)
dict[node].adjacent_nodes.append(new_node)
dict[node].adjacent_nodes.remove(i)
I want my dict[node].adjacent_nodes to be updated only the number of times as there are elements in dict[node].adjacent_nodes initially. This does not happen. What am I missing?
__
For example if dict[node].adjacent_nodes = [1,2] initially. Then my for loop should run 2 times. Each time creating a new_node and adding to dict[node].adjacent_nodes. At the end the for loop should terminate with dict[node].adjacent_nodes = [create_node(1), create_node(2)]
You didn't specify a full working example of the problem with output vs expected output, so I'll guess some possible issues:
A recursive loop can occur in the creation of this compound node object - in the create_node() part or in the copy.deepcopy() (complex objects that include a direct or indirect reference to self).
While doing the copy.deepcopy() you might copy some data that is later causing a problem as it is not meant to be copied (e.g. the global state of the graph etc.).
create_node() affects the itterable or the adjacent_nodes structures.
The append or remove do not behave the way you expect them to in your data struct.
Hope some of it helps you.
I have a function remove_it() that tries to remove some data and the removed data is added to the set removed. The main logic is that if there is more to remove, keep removing and my code looks like this:
removed = set()
prev_count = -1
while prev_count != len(removed):
prev_count = len(removed)
remove_it()
It bothers me a little that the while loop condition and the next line look very similar to each other. Is it normal or is there a better way to do it?
The logic in remove_it() is quite complicated: it detects some graph structure topology and after each round of removal the topology changes and I cannot know how it changes until the removal is done.
I was thinking of return bool value from remove_it() to track whether the set removed has changed. Then the while loop would be like
while remove_it():
pass
which is also strange to me. Is there a better way?
Your remove_it function has side effects and this makes program harder to read. You can rewrite it so that instead of modifying global removed variable it would return set of removed values. Then you can rewrite the loop:
removed = set()
while True:
removed_batch = remove_it()
if removed_batch:
removed += removed_batch
else:
break
I'm currently making my first project in Python - tic tac toe as i thought it would be a good place to start and I've finally hit a road block.
I've currently got the board setup as a list - Board = [1,2,3...,9] and to reset, Board's contents is deleted and re-entered by a separate list however it also adds the brackets.
Is there a way to grab the contents of a separate list without also grabbing the brackets?
if newGame == 'Y' or 'y':
del Board[:]
Board.append(startBoard)
print Board #for testing
else:
sys.exit('game over')
What I'm getting is looking like this:
[[1,2,3,4,5,6,7,8,9]]
Use extend.
Board.extend(startBoard)
Alternatively you can do:
Board = [el for el in startBoard]
and omit the del Board[:] althogether.
Alternatively you can use the copy module:
Board = copy.deepcopy(startBoard)
For me the best will be this though:
Board = [i+1 for i in xrange(9)]
Or the simpler:
Board = range(1, 10) # python 2
or
Board = list(range(1, 10)) # python 3
As zehnpaard suggested in the comments.
Also you can do what Erik Allik has proposed in his answer.
if you want to clear out and modify the contents of a list in-place (as opposed to creating a new fresh list and assigning it back to the variable that holds your old list):
board[:] = startBoard
which, if nothing that needs to see the latest board contents points to the old list, is functionally equivalent to:
board = startBoard
you can get an idea of what it means to modify something in-place vs create a fresh copy/instance if you play around a little bit with assigning the same contents to multiple variables without making copies in the process.
Also, note that since startBoard in your case is a constant, you want to make sure nothing ever modifies it, so the 2nd example is really a very bad idea. There's also however a 3rd:
board = startBoard[:]
which is actually by far the best of all three. What it does is make a copy of startBoard and assign it to the variable board without ever modifying the old list board was pointing to. Also, because you're using a copy of startBoard, you can be sure your start board is always the same in the future.
Note that these aspects arise only in programming languages or styles where mutable datatypes are used; in Functional Programming, almost nothing ever gets modified so you can completely become ignorant of worrying about causing accidental adverse side-effect by touching something someone else is relying on.
Furthermore: note that copying a list can be done in a multitude of ways in Python; from a high level point of view which I'm currently speaking out for there is little difference though, so copy.copy(startBoard) is the same as [x for x in startBoard) is the same as startBoard[:] etc.
See also the PEP8 which provides you with useful coding conventions.
Try this:
for x in startBoard:
Board.append(x)
I have a list of items and would like to generate all possible subsets. Therefore I'm using a recursive function with the item number and a list of all selected items as parameters. The function is called with 0 as the first parameter and does the following:
It looks at the item described by the index parameter
It selects it
It calls itself with an incremented index parameter
It deselects the item
It calls itself with an incremented index parameter
I'm needing the possible subsets to optimise something but since the list will get very long, I can't look at all of them. At first I tried to use brute force to take all subsets into consideration but that was a naive idea. Now the new plan is to create a greedy algorithm that takes the first "useful" selection: I want to look at all subsets until I find one that suits my needs and figured that python's yield statement is exactly the right choice. Here's some code:
def bruteForceLeft(selected,index):
#left is the list of which i need subsets
#its a gobal variable. to test the code, just make sure that you have a
#list called left in scope
if index==len(left):
#print(selected)
yield selected
else:
#the algorithm stores the selection in a tuple of two lists
#that's necessary since there's a second list called right as well
#I think you can just ignore this. Think of selected as a list that
#contains the current selection, not a tuple that contains the current
#selection on the right as well as the left side.
selected[0].append(left[index])
bruteForceLeft(selected,index+1)
selected[0].pop()
bruteForceLeft(selected,index+1)
#as you can see I pass a tuple of two empty lists to the function.
#only the first one is used in this piece of code
for option in bruteForceLeft( ([],[]) ,0):
print(option)
#check if the option is "good"
#break
The output is: nothing
At first I thought that I had made an error in generating the subsets, but in the if condition you can see that I have a commented print statement. If I uncomment this print statement and instead comment out the yield statement all the possible choices are printed - and the for loop is broken
With the yield statement the code runs without error, but it doesn't do anything either.
The problem is that when you recursively call bruteForceLeft, the yielded values don't magically get yielded from the enclosing function. So, you need to re-yield them yourself:
def bruteForceLeft(selected,index):
#left is the list of which i need subsets
if index==len(left):
#print(selected)
yield selected
else:
#the algorithm stores the selection in a tuple of two lists
#that's necessary since there's a second list called right as well
#I think you can just ignore this. Think of selected as a list that
#contains the current selection, not a tuple that contains the current
#selection on the right as well as the left side.
selected[0].append(left[index])
for s in bruteForceLeft(selected,index+1):
yield s
selected[0].pop()
for s in bruteForceLeft(selected,index+1):
yield s
(Edit: I actually just tested this, and your code has errors, but I'm pretty sure not re-yielding is the problem)
"Learning Python, 4th Ed." mentions that:
the enclosing scope variable is looked up when the nested functions
are later called..
However, I thought that when a function exits, all of its local references disappear.
def makeActions():
acts = []
for i in range(5): # Tries to remember each i
acts.append(lambda x: i ** x) # All remember same last i!
return acts
makeActions()[n] is the same for every n because the variable i is somehow looked up at call time. How does Python look up this variable? Shouldn't it not exist at all because makeActions has already exited? Why doesn't Python do what the code intuitively suggests, and define each function by replacing i with its current value within the for loop as the loop is running?
I think it's pretty obvious what happens when you think of i as a name not some sort of value. Your lambda function does something like "take x: look up the value of i, calculate i**x" ... so when you actually run the function, it looks up i just then so i is 4.
You can also use the current number, but you have to make Python bind it to another name:
def makeActions():
def make_lambda( j ):
return lambda x: j * x # the j here is still a name, but now it wont change anymore
acts = []
for i in range(5):
# now you're pushing the current i as a value to another scope and
# bind it there, under a new name
acts.append(make_lambda(i))
return acts
It might seem confusing, because you often get taught that a variable and it's value are the same thing -- which is true, but only in languages that actually use variables. Python has no variables, but names instead.
About your comment, actually i can illustrate the point a bit better:
i = 5
myList = [i, i, i]
i = 6
print(myList) # myList is still [5, 5, 5].
You said you changed i to 6, that is not what actually happend: i=6 means "i have a value, 6 and i want to name it i". The fact that you already used i as a name matters nothing to Python, it will just reassign the name, not change it's value (that only works with variables).
You could say that in myList = [i, i, i], whatever value i currently points to (the number 5) gets three new names: mylist[0], mylist[1], mylist[2]. That's the same thing that happens when you call a function: The arguments are given new names. But that is probably going against any intuition about lists ...
This can explain the behavior in the example: You assign mylist[0]=5, mylist[1]=5, mylist[2]=5 - no wonder they don't change when you reassign the i. If i was something muteable, for example a list, then changing i would reflect on all entries in myList too, because you just have different names for the same value!
The simple fact that you can use mylist[0] on the left hand of a = proves that it is indeed a name. I like to call = the assign name operator: It takes a name on the left, and a expression on the right, then evaluates the expression (call function, look up the values behind names) until it has a value and finally gives the name to the value. It does not change anything.
For Marks comment about compiling functions:
Well, references (and pointers) only make sense when we have some sort of addressable memory. The values are stored somewhere in memory and references lead you that place. Using a reference means going to that place in memory and doing something with it. The problem is that none of these concepts are used by Python!
The Python VM has no concept of memory - values float somewhere in space and names are little tags connected to them (by a little red string). Names and values exist in separate worlds!
This makes a big difference when you compile a function. If you have references, you know the memory location of the object you refer to. Then you can simply replace then reference with this location.
Names on the other hand have no location, so what you have to do (during runtime) is follow that little red string and use whatever is on the other end. That is the way Python compiles functions: Where
ever there is a name in the code, it adds a instruction that will figure out what that name stands for.
So basically Python does fully compile functions, but names are compiled as lookups in the nesting namespaces, not as some sort of reference to memory.
When you use a name, the Python compiler will try to figure out where to which namespace it belongs to. This results in a instruction to load that name from the namespace it found.
Which brings you back to your original problem: In lambda x:x**i, the i is compiled as a lookup in the makeActions namespace (because i was used there). Python has no idea, nor does it care about the value behind it (it does not even have to be a valid name). One that code runs the i gets looked up in it's original namespace and gives the more or less expected value.
What happens when you create a closure:
The closure is constructed with a pointer to the frame (or roughly, block) that it was created in: in this case, the for block.
The closure actually assumes shared ownership of that frame, by incrementing the frame's ref count and stashing the pointer to that frame in the closure. That frame, in turn, keeps around references to the frames it was enclosed in, for variables that were captured further up the stack.
The value of i in that frame keeps changing as long as the for loop is running – each assignment to i updates the binding of i in that frame.
Once the for loop exits, the frame is popped off the stack, but it isn't thrown away as it might usually be! Instead, it's kept around because the closure's reference to the frame is still active. At this point, though, the value of i is no longer updated.
When the closure is invoked, it picks up whatever value of i is in the parent frame at the time of invocation. Since in the for loop you create closures, but don't actually invoke them, the value of i upon invocation will be the last value it had after all the looping was done.
Future calls to makeActions will create different frames. You won't reuse the for loop's previous frame, or update that previous frame's i value, in that case.
In short: frames are garbage-collected just like other Python objects, and in this case, an extra reference is kept around to the frame corresponding to the for block so it doesn't get destroyed when the for loop goes out of scope.
To get the effect you want, you need to have a new frame created for each value of i you want to capture, and each lambda needs to be created with a reference to that new frame. You won't get that from the for block itself, but you could get that from a call to a helper function which will establish the new frame. See THC4k's answer for one possible solution along these lines.
The local references persist because they're contained in the local scope, which the closure keeps a reference to.
I thought that when a function exits, all of its local references disappear.
Except for those locals which are closed over in a closure. Those do not disappear, even when the function to which they are local has returned.
Intuitively one might think i would be captured in its current state but that is not the case. Think of each layer as a dictionary of name value pairs.
Level 1:
acts
i
Level 2:
x
Every time you create a closure for the inner lambda you are capturing a reference to level one. I can only assume that the run-time will perform a look-up of the variable i, starting in level 2 and making its way to level 1. Since you are not executing these functions immediately they will all use the final value of i.
Experts?