Python .append() method is acting weirdly [duplicate] - python

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 1 year ago.
list = [[0,0]]
x = [0,0]
for i in range(5):
x[0] += 1
list.append(x)
expected result: [[1,0],[2,0],[3,0],[4,0],[5,0]]
actual result: [[5,0],[5,0],[5,0],[5,0],[5,0]]
I have tried several things, but none seem to work.
I am open to any suggestions, I am trying to keep "x" as a list and would prefer to stay away from doing something like
x1 = x[0]
x2 = x[1]

I think the problem is that it’s appending the list, not its contents, so it changes each time to the current value of the list(x). However, I’m really not sure what the exact problem is.
You could solve your problem by doing the following:
List=[[0,0]]
x=0
for I in range(5):
x += 1
list.append([x,0])

Related

Why do variables sometimes bind both directions in Python? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 3 years ago.
Say I have
x = [[0,0]]
y = x[-1]
Then why does
y[1] += 1
give
x = [[0,1]]
y = [0,1]
That is, I'm confused as to why it also changes what x is, even though I only specified something to do with y?
This makes sense if you think of a list as a mutable object in memory and you consider that you're modifying that list.
The variables are simply different names for that same list.
That code is equivalent to:
list_obj = [0, 0]
x = [ list_obj ] # a list with list_obj as
# its single element
y = list_obj # same as x[-1], just
# another name for list_obj
Then it's natural that you're simply modifying list_obj[1] in both cases.

Variable in while loop not incrementing after for loops [duplicate]

This question already has answers here:
Appending to list with loop
(2 answers)
Closed 3 years ago.
I am trying to create a cartesian product of the alphabet with loops. I have for loops that create the desired output but i in my while loop is never reached for some reason.
This loop is running forever in a jupyter lab notebook.
lower_az = [chr(ord('a') + i) for i in range(26)]
i=0
n=2
lst = lower_az.copy()
final_list = []
while i < n:
for let in lst:
for j in range(26):
strng = let + lower_az[j]
lst.append(strng)
i += 1
final_list.append(lst)
Unless I am missing something obvious the variable i should increment until it reaches n and stop the while loop at the desired length of strings.
You are changing the list you are iterating over. The problem is not the while-loop, it's the lst.append(strng) while iterating for let in lst.
#blue_note is correct - Python doesn't behave well when you change a list you're iterating over.
It looks like this is just a typo, though: you've got final_list all ready to receive the elements. To fix this, change:
lst.append(strng)
to
final_list.append(strng)
and drop final_list.append(lst) and your program appears to work fine.

Iterating - Python [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 5 years ago.
Trying to remove negative numbers from a list. I kept running into an issue where two successive negative numbers did not get removed. My code is quite simple:
numbers = [-5, 1, -3, -1]
def remove_neg(num_list):
for item in num_list:
if item < 0:
num_list.remove(item)
print(remove_neg(numbers))
#[1, -1]
I found the answer online after trying 4 different versions of my code and pulling a few hairs out of my head. The answer I found assigned r = numbers[:] and then removed items from r instead of the initial list.
def remove_neg(num_list):
r = numbers [:]
for item in num_list:
if item < 0:
r.remove(item)
print(r)
I understand this concept to have two list variables point to separate data. What I don't understand, is why my initial code doesn't work. Shouldn't for i in numbers: iterate through every item in the list? Why would two successive numbers not be treated the same? I've scoured looking for why and can't seem to find an answer.
In the first example you're modifying the list while iterating over it, which, as you've seen, messes up the iteration. While the second example works, it's very inefficient, and it would be much easier to use a list comprehension to construct a new list without the negatives:
def remove_neg(num_list):
return [x for x in num_list if x > 0]

For loop iterating not executed with condition set inside [duplicate]

This question already has answers here:
Python list problem [duplicate]
(2 answers)
Closed 5 years ago.
I have a simple python loop that iterate over a 2D list which has 1000 sublist inside. Each sublist will contain 3 string values. I only want to change the sublists which are after the 365th sublist. I also have a very trivial condition which will decide if an operation will be applied to the element. My minimum code is as follows:
def change_list(arr):
for i in range(len(arr)):
if i < 365:
pass
else:
arr[i][1] = str(int(arr[i][1]) * 2)
When apply this function in main I'll simply invoke this function as: change_list(parsed_lines). For parsed lines, I'll just give a simple example:
parsed_lines = [["afkj","12","234"]] * 1000
My function will do the "multiply by 2" operation on all sublists, which is an unexpected behavior. I've tried not using conditions, but results in the same behavior.
for i in range(365, len(arr)):
arr[i][1] = str(int(arr[i][1]) * 2)
Then I tried the other way to iterate my arr as:
for line in arr:
if arr.index(line) < 365:
print("I'm less than 365")
else:
line[1] = str(int(line[1]) * 2)
but this iteration will never execute the block under else. I am very confused by this, hope someone can help.
Update:
The expected behavior should be:
For arr[0: 365], the sublist will stay the same as: [["afkj","12","234"]]
For arr[365:], the sublist will be: [["afkj","24","234"]]
Your problem, as described, is not in the program, but in the test set. parsed_lines = [["afkj","12","234"]] * 1000 creates a list of 1000 references to the same list ["afkj","12","234"]. When it is modified through any of those references (say, above 365), it is seen as modified through any of those references (even below 365). In other words, parsed_lines[0][0]='foo' makes all fisrt elements in all sublists 'foo'.

Python - Copying lists in a loop [duplicate]

This question already has answers here:
How do I clone a list so that it doesn't change unexpectedly after assignment?
(24 answers)
Closed 6 years ago.
I'm kinda new to python... So I've been strugling with a problem for a while and after doing a huge research I did not find solution so I decided to ask here :).
So the code that is explaining my problem:
test = []
solutions = []
i = 0
while i < 100:
for i in range(0, 64):
pos = random.randrange(0, 64)
test.append(pos)
solutions.append(test)
test.clear()
i += 1
So I want to add a copy of a table to another table everytime the loop goes and then clean the table named test. The problem is I don't know how to create a copy of list each time the loop goes. So I'm getting list of empty lists :(
I tried with copy.copy or copy.deepcopy but that didn't work.
That is my first question here so sorry for any "errors" also I'm not native english speaker but I hope you will be able to understand me.
You can append duplicates by calling the list constructor
solutions.append(list(test))
You can do copy the list like:
solutions.append(test[:])
And to empty it, since there is no empty method, you can just reassign it to a new empty list:
test = []
Like Zaphod mentioned, your while loop never finished, since you were never updating the value of i, plus is was being assigned in the inner for loop anyway. Why not use two nested for loops? (the underscore is just a var placeholder signifying the value is not used)
import random
test = []
solutions = []
for _ in range(0, 100):
for i in range(0, 64):
pos = random.randrange(0, 64)
test.append(pos)
solutions.append(test[:])
test = []
print solutions
if you want clean simply dont use test.clear()
use:
test = []
you should remove the test.clear(), and change <100 of while because is infinite
import random
test = []
solutions = []
i = 0
while i < 100:
for i in range(0, 64):
pos = random.randrange(0, 64)
test.append(pos)
solutions.append(test)

Categories

Resources