Odd behaviour of Python lists [duplicate] - python

This question already has answers here:
Creating functions (or lambdas) in a loop (or comprehension)
(6 answers)
Closed 6 years ago.
Is it possible that when appending lists of function objects in Python 3, the order gets lost?
My understanding was that Python lists are ordered and indeed running
numbers = []
for i in range(10):
numbers.append(i)
print(numbers)
returns [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] as expected.
If I append function objects however, like in this MWE:
functions = []
for k in range(10):
def test():
print('This is the %i th function.' %k)
functions.append(test)
and call functions[2]() I get This is the 9 th function.
Can somebody make sense of this odd behaviour?

A function closure does not capture the value of a variable when it is defined, it captures the name of the variable.
Thus, the function you have stored in functions[2] references k. When you call it, it will show you the value of k when it is called, not when it was defined.

Related

How do I create a remove every other element function? [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 7 months ago.
I have written a script
def remove_every_other(my_list):
# Your code here!
rem = False
for i in my_list:
if rem:
my_list.remove(i)
rem = not rem
return my_list
It removes every other element from the list.
I input [1,2,3,4,5,6,7,8,9,10] it returns [1,3,4,6,7,9,10]
Which to me is very strange also if I input [Yes,No,Yes,No,Yes]
it outputs [Yes,No,Yes,No]
I have tried to figure it out for hours but couldn't get it to work, I am a beginner.
You could just use slicing for that. Or do you want to do it explicitly in a loop? For an explanation of the syntax, you can follow the link. Basically you take the full list (no start or end defined) with a step-value of 2 (every other element). As others have pointed out, you run into problems if you're modifying a list that you're iterating over, thus the unexpected behavior.
input_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
output_list = input_list[::2]
print(output_list)
This returns a copy of the list with every other element removed:
[1, 3, 5, 7, 9]
Since .remove() is being called upon the same list that you're iterating over, the order is getting disarranged.
We could append the items that you want at the end in another list to maintain the ordering in the original list.
def remove_every_other(my_list):
morphed_list = []
rem = True
for i in my_list:
if rem:
morphed_list.append(i)
rem = not rem
return morphed_list
In general, it is not a good idea to modify the list you're iterating over. You could read more about it over here: https://stackoverflow.com/questions/10812272/modifying-a-list-while-iterating-over-it-why-not#:~:text=The%20reason%20to%20why%20you,list%20of%20just%20odd%20numbers.

Why python showing none as an output while print list methods inside print()? [duplicate]

This question already has answers here:
Why do these list operations (methods: clear / extend / reverse / append / sort / remove) return None, rather than the resulting list?
(6 answers)
Closed 8 months ago.
Whenever I use list methods in the print function, it gives none as an output, but if I apply methods and store in it variable before print() and then print that variable, only it will provide the desired result. Why? Let me show you what I am talking about:
l = [9, 4, 7, 1, 2]
print(l.sort())
None
But tuple can give the output in the print function.
List methods are indeed functions that modify the value of the Python list. These functions don't return any value because their purpose is to perform operations directly on the corresponding list values.
However, there are some special build-in functions like sorted() as you can see in the following example, which return the modified list, instead of just changing its values and returning None :
> l = [9, 4, 7, 1, 2]
> print(l.sort())
None
> print(sorted(l))
[1, 2, 4, 7, 9]
When you invoke list.sort(), the list is sorted but if you try to print the outcome of the function, you will find that the function is not coded to give any out value, so you will get None. As shown in the question comments, you can learn more about this behavior on the official Python documentation.

Python for loop weird bug [duplicate]

This question already has answers here:
Why can I use a list index as an indexing variable in a for loop? [duplicate]
(6 answers)
Are for-loop name list expressions legal?
(2 answers)
Closed last year.
So in a quiz, I have given the question what the execution of this block of code gives (The one under).
a = [0, 1, 2, 3]
for a[0] in a:
print(a[0])
I had selected error but to my surprise, it actually works and is able to print all the elements inside the list. But how?
firstly the element getting variable (usually i) is shadowing the actual variable on top of that we are getting the first element inside a number so how is it working.
a[0] is type of a so it can be used to iterate over the array but as in look you are assigning value in a[0] it's value will change to last element of the array.
a = [0,1,2,3]
for a[0] in a:
print(a[0]
Will result in:
0
1
2
3
But now printing a will give you modified array:
print(a)
[3, 1, 2, 3]

Appending a global list to a global list? [duplicate]

This question already has answers here:
Why does foo.append(bar) affect all elements in a list of lists?
(3 answers)
Value changes in new list impact previous list values, within a list of lists [duplicate]
(2 answers)
Python append behaviour odd? [duplicate]
(3 answers)
Closed 4 years ago.
I have written following code for solving the n-Queens problem where we have to find all possible legal (non-attacking) placements of n queens in an n*n chessboard. The code uses the standard backtracking solution.
Here the method n_queens uses the helper method solve_n_queens which uses recursion. The outer method just initializes global lists result & col_placement and calls the helper method.
def n_queens(n):
def solve_n_queens(row):
if row == n: # all queens are legally placed
result.append(list(col_placement))
return
for col in range(n):
# check if new queen is either 1) in same column or 2) same diagonal with any previously placed queen
if all(abs(col-c) not in (0, row-r)
for r, c in enumerate(col_placement[:row])):
col_placement[row] = col
solve_n_queens(row+1)
result, col_placement = [], [0] * n # result is empty initially; [0] * n means no queen is placed
solve_n_queens(0)
return result
This gives erroneous output for n_queens(4)
[[3, 1, 2, 1], [3, 1, 2, 1]]
However it is not an algorithmic bug because just altering the 4th line result.append(col_placement) to result.append(list(col_placement)) mysteriously gives the correct output
[[1, 3, 0, 2], [2, 0, 3, 1]]
What I don't grok is when col_placement is already a list, why do we need to call the list method?
The problem is that without using list you are appending a reference to the same and only list col_placement you are working with (as you can see the results are not only wrong, but they are also the same). Using list creates a new copy (a instant snapshot of col_placement) that will not be modified when col_placement does as you keep going through the rest of the program.
So essentially list(col_placement) is the same as col_placement.copy() or col_placement[:].

What is Callback in python? [duplicate]

This question already has answers here:
How can I provide a "callback" to an API?
(5 answers)
Closed 5 years ago.
I want to create a list of squares of even numbers by creating a list, applying the callback functions to each element of the list and puts the result in a list. But how do I implement callback in the first place?
In this case I think you are looking for the map builtin. It takes a function and a list and then applies that function on the list storing each result as it goes. For example:
def square(x):
return x * x
list(map(square, [1, 2, 3, 4]))
>>> [1, 4, 9, 16]
Note that we need to cast the result of map back to a list since it returns a map object.

Categories

Resources