Negative number in python list [duplicate] - python

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Strange result when removing item from a list while iterating over it
(8 answers)
Closed 1 year ago.
items = [10, 5, -2, 23, 5, 6,7]
For i in items:
if i <= 5:
items.remove(i)
print(items)
Does anybody know why -2 is not taken into account in for loop? It works if the condition is i < 5 but -2 is passed over when the condition is <=

The answer is quite simple. If you change the object you are working with, it will restructure automatically. What is happening is the following:
Your starting list -> [10, 5, -2, 23, 5, 6, 7]
Step 0. First iteration of the loop (checks the first element of the list) -> 10 <= 5 False
Step 1. Second iteration of the loop (checks the second item in the list) -> 5 <= 5 True
Your current list -> [10, -2, 23, 5, 6, 7]
Step 2. Third iteration of the loop (checks the third item in the list) -> 23 <= 5 False
As you can see, when you removed the number 5, the -2 became the second item in the list. However, the for loop does not know this, and it will continue to search with the next values ​​thinking that it has already checked for -2, since it is now the second value in the list.
This is why it is not recommended to change objects while iterating with them.

Try to filter the list and create a new one.
numbers= [10, 5, -2, 23, 5, 6,7]
positive_numbers = [x for x in numbers if x > 0]

Related

python homework interleaving list

The problem statement is:
Design and implement an algorithm that displays the elements of a list
by interleaving an element from the beginning and an element from the
end.
For example, input:
1 2 3 4 5 6 7 8
Output :
1 8 2 7 3 6 4 5
This is what I tried, but I don't know what happen with elements 7 and 8:
lista = [1, 2, 3, 4, 5, 6, 7, 8]
for i in range(len(lista)):
lista.insert(2*i-1,lista.pop())
print("The list after shift is : " + str(lista))
# output:
# The list after shift is : [1, 7, 2, 8, 3, 6, 4, 5]
The only error in you code, is that range(len(lista)) starts from 0, not from 1. By starting from zero, in the first iteration 2*i-1 will be 2*0-1 = -1, and hence lista.insert(-1,lista.pop()), which means inserting at the very end of the list (that is what index -1 means in python).
To fix your code, you just need to start the range from 1. Actually, you are iterating too much, you can have your range just from 1 to the half of your list, like this:
lista = [1, 2, 3, 4, 5, 6, 7, 8]
for i in range(1, len(lista)//2):
lista.insert(2*i-1,lista.pop())
print("The list after shift is : " + str(lista))
# output:
# The list after shift is : [1, 8, 2, 7, 3, 6, 4, 5]
When you become more familiarized with the language, you will see that this can be accomplished much more easily.
For example, you can use the python slice syntax to achieve your goal. You slice from beginning to half , and from end to half (step of -1), then zip then together and flat.
[i for z in zip(lista[:4],lista[:-5:-1]) for i in z]
# [1, 8, 2, 7, 3, 6, 4, 5]
Another option:
import math
lista = [1, 2, 3, 4, 5, 6, 7, 8]
ans = []
for i in range(math.floor(len(lista)/2)):
ans.append(lista[i])
ans.append(lista[-i-1])
if (len(lista) % 2) != 0:
ans.append(lista(math.ceil(len(lista)/2)))
print(ans)
Technically speaking, I'd say it's two off-by-one errors (or one off-by-one error, but from -1 to +1, you'll see what I mean in the second paragraph). The first one is that you're subtracting 1 when you shouldn't. In the case when i = 0 (remember that range(n) goes from 0 to n-1), the insert position is being evaluated as 2*0-1 = (2*0)-1 = 0-1= -1 (for insert() method, that's the last position of the original list, pushing what was there forward, so it'll be the penultimate position of the NEW list).
But, when you remove the -1, the output becomes 8 1 7 2 6 3 5 4, which is close to what you want, but not quite right. What's missing is that the elements inserted should be at positions 1, 3, 5, 7, and not 0, 2, 4, 6. So, you'll actually need to add 1.
So, the shortest change to fix your code is to change lista.insert(2*i-1,lista.pop()) to lista.insert(2*i+1,lista.pop()).
Notice: if you put a print inside for, you'll realize that, after changing half the elements, the output is already right. That's because when len(lista) is 8, and you do lista.insert(x, lista.pop()) where x is bigger than 8, basically you're removing the last element (pop) and adding it at the end, so, nothing changes. Hence, you could also change range(len(lista)) to range(len(lista)//2). Test if it'll work when len(lista) is odd

how to identify duplicate integers within a list, than minus each integer following the duplicate by one?

I am trying to solve an issue that I am currently running into. I want to have to have a list that is made up of only random integers. Then if i find a duplicate integer within this list i want to minus the rest of the list by one, after the second time the duplicate number appeared. Furthermore if a second pair of duplicate numbers are encountered, it should then minus the rest of the list by two, than if a third by three and etc.
But it should not affect the same duplicate number or any other duplicated number (that differs from the first) that is in the sequence.
For example
mylist = [0 1 2 3 4 5 6 2 8 5 10 11 12 1 14 15 16 17]
I want the end result to look like;
mylist = [0 1 2 3 4 5 6 2 7 5 9 10 11 1 12 13 14 15]
I have some rough code that I created to attempt this, but it will always minus the whole list including duplicated integers (the first pairs and any further pairs).
If someone can shed some light on how to deal with this problem i will be highly grateful!
Sorry forgot to add my code
a = [49, 51, 53, 56, 49, 54, 53, 48]
dupes = list()
number = 1
print (dupes)
while True:
#move integers from a to dupes (one by one)
for i in a[:]:
if i >= 2:
dupes.append(i)
a.remove(i)
if dupes in a:
a = [x - number for x in a]
print (dupes)
print(dupes)
if dupes in a:
a = [x - number for x in a]
number = number+1
break
Forgot to mention earlier, me and friend are currently working on this problem and the code i supplied is our rough outline of what is should look like and now the end result, I know that it does now work so i decided to ask for help for the issue
You need to iterate through your list and when you encounter a duplicate(can use list slicing) then decrement the next item!
List slicing - example,
>>> L=[2,4,6,8,10]
>>> L[1:5] # all elements from index 1 to 5
[4, 6, 8, 10]
>>> L[3:] # all elements from index 3 till the end of list
[8, 10]
>>> L[:2] # all elements from index beginning of list to second element
[2, 4]
>>> L[:-2] # all elements from index beginning of list to last second element
[2, 4, 6]
>>> L[::-1] # reverse the list
[10, 8, 6, 4, 2]
And enumerate
returns a tuple containing a count (from start which defaults to 0)
and the values obtained from iterating over sequence
Therefore,
mylist=[0, 1, 2, 3, 4, 5, 6, 2, 8, 5, 10, 11, 12, 1, 14, 15, 16, 17]
dup=0
for index,i in enumerate(mylist):
if i in mylist[:index]:
dup+=1
else:
mylist[index]-=dup
print mylist
Output:
[0, 1, 2, 3, 4, 5, 6, 2, 7, 5, 8, 9, 10, 1, 11, 12, 13, 14]

iPython 3.5.2 lists [duplicate]

This question already has answers here:
Python - How to extract the last x elements from a list [duplicate]
(4 answers)
Closed 6 years ago.
I have created a list size 12, ex: V[0 1 2 3 4 5 6 7 8 9 10 11]
How do I return only the last 10 digits [2:11]? Also what if the list had n variables, I tried V[2,:], but I get TypeError: list indices must be integers or slices, not tuple.
If you want to get the last x elements of a list, you need to use a negative index in your slice.
>>> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> numbers[-5:]
[5, 6, 7, 8, 9]
As for the error you mentioned, it looks like you have a stray comma after the 2, which makes 2 the first element in a tuple. Take out the comma and it should be a valid slice.

Python: for-loop wrong output [duplicate]

This question already has answers here:
Removing elements from a List in Python
(3 answers)
Closed 6 years ago.
Can't understand why it missing some indexes in loop?
Index number 3 for example.
I just want to delete the unique elements this way. I know another one but I don't know what's wrong with this one (or me).
lst = [2, 7, 1, 9, 3, 5, 2, 1]
def check(lst):
result = lst
print(lst) #checking
for num in lst:
print("index:", num) #checking
print("num:", num) #checking
if lst.count(num) < 2:
print("count:", lst.count(num)) #checking
result.remove(num)
return(result)
print(check(lst))
Output
[2, 7, 1, 9, 3, 5, 2, 1]
index: 2
num: 2
index: 7
num: 7
count: 1
index: 9
num: 9
count: 1
index: 5
num: 5
count: 1
index: 1
num: 1
[2, 1, 3, 2, 1]
You're removing items from a list as you're iterating over it, which you shouldn't do.
(result = lst does NOT make a copy of lst; it creates a new name which refers to the same object.)
If you just want to remove duplicate elements, you can use a set (although you may lose your ordering):
lst = list(set(lst))

python - How to move back an iteration in a for loop list [duplicate]

This question already has answers here:
Making a python iterator go backwards?
(14 answers)
Closed 6 years ago.
Given the list: a = [1, 2, 3, 4 5] in a for loop, suppose that the current item is 2, and next item is 3. If some condition is true, how can I make the next item be 2 again, which means the iteration should continue from 2 again instead of 3?
a = [1, 2, 3, 4, 5]
for item in a:
print item
if condition:
do something, and go back to previous iterator
The output would be:
1
2
2
3
4
5
Beware of an infinite loop, and it's not very Pythonic.
i = 0
a = [1, 2, 3, 4, 5]
hasBeenReset = False
while i < len(a):
if a[i] == 3 and not hasBeenReset:
i = 1
hasBeenReset = True
print(a[i])
i += 1

Categories