I am writing a piece of code the this is the scenario I am facing.
How to update the list which is in for-condition, and for the next iteration, the list in for-condition is updated?
Eg.,
list = [0,1,2]
for i in list:
print list[i]
if list[i] == 0:
list.append(3)
The entry '3' should get updated in the list in for-condition.
Is it possible to update the list in for-condition dynamically?
Thanks in advance.
Yes, if you do that, it will work. However, it's usually not a good idea, because it can create confusing interactions between the iteration and the loop-body action. In your example, you add an element at the end, but if, for instance, you change an element in the middle, you may or may not see the change depending on where you are in the list when it happens. (For instance, you could change the value of an element you already iterated past.)
Also, you shouldn't name a variable list, as that shadows the built-in type called list.
Be aware that your loop is incorrect, in Python this snippet:
for e in lst:
… Iterates over each element e in lst, and e is not an index, it's an element - so all the parts in the question where you wrote list[i] are incorrect, they should have been simply i. Try this solution instead, it's equivalent and less error prone:
lst = [0, 1, 2]
print(lst)
lst += [3] * lst.count(0) # add as many 3s at the end as there are 0s in the list
Notice that it's never a good idea to modify a list at the same time you're traversing it. Also, don't use list as a variable name, there's a built-in function with that name.
Related
I'm very new to the world of programming, I've been trying to solve a specific python academic exercise but I ran into an obstacle.
The problem is that I need to generate a lucky numbers sequence, as in the user inputs a sequence [1,...,n] and these steps happen:
Every second element is removed
Every third element is removed
Every fourth element is removed
.
.
.
When it becomes impossible to remove more numbers, the numbers left in the list are "lucky".
This is my code:
def lucky(l):
index = 2
new_list = []
while(index<len(l)):
for i in range(len(l)):
if(i%index==0):
new_list.append(l[i])
index=index+1
return new_list
The while loop is to have the final condition when " it is impossible to remove more numbers". However with every iteration, the list gets shorter more and more, but I don't know how to do it.
My code works for the first condition when index=2(remove every 2nd element), then in the following loops it doesn't work because:
It is still limited by length of the original list.
new_list.append(l[i]) will just add more elements to the new_list, rather than updating it in its place.
I don't know how to update the list without creating multiple amounts of lists and with each iteration adding the new elements to a new list.
Any help is appreciated.
You could use del with appropriate list slicing (see the manual for more details) to update the list in-place:
def lucky(l):
interval = 2
while interval <= len(l):
del l[interval-1::interval]
interval += 1
I am not sure if I understand your question correctly, but you can remove items from your original list via del l[index], where index is the index of the element to be removed.
For more details on lists look here:
https://docs.python.org/3/tutorial/datastructures.html
import math
def lucky(l, index):
for i in range(math.floor(len(l)/index)):
del l[(i+1)*(index-1)]
Not sure if the code will work, as I cannot test it right now. But I think it should work somehow like that.
EDIT:
Tested it and the code works. If you want to run all three steps, just do:
l = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
lucky(l,2)
lucky(l,3)
lucky(l,4)
print(l)
>>>[1,3,7,13,15]
Here's my code
def abc(l,z):
L=[]
länge= len(L)
for x in range(0, länge+1):
L[x]+z
print(L)
abc(["1","2","3"],"-")
I want the program to output "1-2-3"
l in abc(l,z) should be a List out of Strings which combines "l" and "z" to a single String.
I'm getting an Index Error: list index out of range.
There are a couple of issues here.
First, range(0, länge+1) will stop at länge but your list only has indexes from 0 tolänge - 1, so that's one source for an IndexError.
Second, L[x]+z will give you another IndexError because L is empty but you try to access L[0] (and in the next iteration, where you don't get because of the error, L[1], L[2], and so on).
Third, even without an IndexError the statement L[x]+z will do nothing. You compute the value of L[x]+z but then you don't assign any variable to it, so it is immediately lost.
Fourth, in order to print your final result, put the call to print after the for loop, not inside. Consider using return instead of print if you actually want to do something with the result the function produces (make sure to educate yourself on the difference between print and return).
Fifth, you want to build a string, so the usage of the list L does not make much sense. Start with an empty string and add the current item from l and z to it in the loop body (coupled with a re-assignment in order to not lose the freshly computed value).
Lastly, there's no point in using range here. You can iterate over values in a list direclty by simply writing for x in l:.
That should give you enough to work with and fix your code for now.
(If you don't care why your function does not work and this is not an exercise, simply use str.join as suggested in the comments.)
I am trying to append objects to the end of a list repeatedly, like so:
list1 = []
n = 3
for i in range(0, n):
list1 = list1.append([i])
But I get an error like: AttributeError: 'NoneType' object has no attribute 'append'. Is this because list1 starts off as an empty list? How do I fix this error?
This question is specifically about how to fix the problem and append to the list correctly. In the original code, the reported error occurs when using a loop because .append returns None the first time. For why None is returned (the underlying design decision), see Why do these list operations return None, rather than the resulting list?.
If you have an IndexError from trying to assign to an index just past the end of a list - that doesn't work; you need the .append method instead. For more information, see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list?.
If you want to append the same value multiple times, see Python: Append item to list N times.
append actually changes the list. Also, it takes an item, not a list. Hence, all you need is
for i in range(n):
list1.append(i)
(By the way, note that you can use range(n), in this case.)
I assume your actual use is more complicated, but you may be able to use a list comprehension, which is more pythonic for this:
list1 = [i for i in range(n)]
Or, in this case, in Python 2.x range(n) in fact creates the list that you want already, although in Python 3.x, you need list(range(n)).
You don't need the assignment operator. append returns None.
append returns None, so at the second iteration you are calling method append of NoneType. Just remove the assignment:
for i in range(0, n):
list1.append([i])
Mikola has the right answer but a little more explanation. It will run the first time, but because append returns None, after the first iteration of the for loop, your assignment will cause list1 to equal None and therefore the error is thrown on the second iteration.
I personally prefer the + operator than append:
for i in range(0, n):
list1 += [[i]]
But this is creating a new list every time, so might not be the best if performance is critical.
Note that you also can use insert in order to put number into the required position within list:
initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]
And also note that in python you can always get a list length using method len()
Like Mikola said, append() returns a void, so every iteration you're setting list1 to a nonetype because append is returning a nonetype. On the next iteration, list1 is null so you're trying to call the append method of a null. Nulls don't have methods, hence your error.
use my_list.append(...)
and do not use and other list to append as list are mutable.
I am trying to append objects to the end of a list repeatedly, like so:
list1 = []
n = 3
for i in range(0, n):
list1 = list1.append([i])
But I get an error like: AttributeError: 'NoneType' object has no attribute 'append'. Is this because list1 starts off as an empty list? How do I fix this error?
This question is specifically about how to fix the problem and append to the list correctly. In the original code, the reported error occurs when using a loop because .append returns None the first time. For why None is returned (the underlying design decision), see Why do these list operations return None, rather than the resulting list?.
If you have an IndexError from trying to assign to an index just past the end of a list - that doesn't work; you need the .append method instead. For more information, see Why does this iterative list-growing code give IndexError: list assignment index out of range? How can I repeatedly add elements to a list?.
If you want to append the same value multiple times, see Python: Append item to list N times.
append actually changes the list. Also, it takes an item, not a list. Hence, all you need is
for i in range(n):
list1.append(i)
(By the way, note that you can use range(n), in this case.)
I assume your actual use is more complicated, but you may be able to use a list comprehension, which is more pythonic for this:
list1 = [i for i in range(n)]
Or, in this case, in Python 2.x range(n) in fact creates the list that you want already, although in Python 3.x, you need list(range(n)).
You don't need the assignment operator. append returns None.
append returns None, so at the second iteration you are calling method append of NoneType. Just remove the assignment:
for i in range(0, n):
list1.append([i])
Mikola has the right answer but a little more explanation. It will run the first time, but because append returns None, after the first iteration of the for loop, your assignment will cause list1 to equal None and therefore the error is thrown on the second iteration.
I personally prefer the + operator than append:
for i in range(0, n):
list1 += [[i]]
But this is creating a new list every time, so might not be the best if performance is critical.
Note that you also can use insert in order to put number into the required position within list:
initList = [1,2,3,4,5]
initList.insert(2, 10) # insert(pos, val) => initList = [1,2,10,3,4,5]
And also note that in python you can always get a list length using method len()
Like Mikola said, append() returns a void, so every iteration you're setting list1 to a nonetype because append is returning a nonetype. On the next iteration, list1 is null so you're trying to call the append method of a null. Nulls don't have methods, hence your error.
use my_list.append(...)
and do not use and other list to append as list are mutable.
As the topic states:
list = ["a", "b"]
element = "ac"
Can I use the:
if element in list:
If element is equal to the element in (list + "c")
Pseudocode to what I want to achieve:
if element in (list+c)
What is the best way to get this behavior in python?
Edit: I know there are many ways to get around this, but can this be done in one line as the code above.
More efficient would be:
if any(x+'c' == element for x in your_list):
as it avoids scanning through the list twice (once to make the "+c" versions, once to check if element is in the resulting list). It'll also "short-circuit" (that is, quickly move on) if it finds the element before going through the entire list.
P.S. - it's best not to name variables list, since that's already the name for the actual list type.
if element in [elem + 'c' for elem in my_list]:
# ...
Never a good practice to call a variable list (or int, float, map, tuple, etc.), because you are loosing those built-in types.
if element[0] in list:
You don't want to add "c" to every item in the list and check to see whether "ac" is in the resut; you want to check to see if the first letter of "ac" is in the list. It's the same thing except a lot easier.
if element[:-1] in list:
It is better to calculate the element without 'c'. So you are making just one calculation.