bring back removed elements from list? - python

i've got this code (part of game i'm trying to make) that checks the elements of a list with elements of another list...basically, what it does is compare each index of each element, if the 2 index are equal it removes it from the list
here's that code:
checkctr = 0
x = 0
while checkctr < 4:
if p1guesslist[x] == hidden[x]:
black += 1
p1nonhidden.remove(hidden[x]) #p1nonhidden is a copy of hidden
p1nonmatch.remove(hidden[x]) #p1nonmatch is a copy of p1guesslist
x += 1
checkctr += 1
for p1guess in p1nonmatch: #p1guess is a 4 digit user input
if p1guess in p1nonhidden:
white += 1
an example of how the code works in the output:
hidden = [1, 1, 2, 3] #elements of this is randomly generated
p1guesslist = [1, 3, 2, 4] #elements of this list is from p1guess
black = 2 #initial value is 0
white = 1 #initial value is 0
if the index of both list is equal, black gets +1 and gets removed from the list. the remaining elements is then checked if they are in the list of hidden, if they are -white gets +1
the problem is, the program is supposed to ask for user input until a certain amount of number is reached, so p1guesslist changes elements every input..what happens is this:
hidden = [1, 1, 2, 3]
p1guesslist = [1, 3, 2, 4] #first input
black = 2
white = 1
p1guesslist = [1, 1, 2, 3] #second input
ValueError: list.remove(x): x not in list
i am aware that because of the list.remove() the ValueError occurs...
so i was thinking if there is a way to bring back the elements that was removed from hidden to after checking is done to avoid the error
*i put a mini version of the game in this online notepad just incase you want to see it http://shrib.com/UMYKxGiY i used Python 3.4.1 to make that

Handle the exception:
try:
list.remove(x)
except ValueError:
pass
. No more "x not in list."

Related

Trying to make a function to find a specified target [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
So I am trying to make a searching function. But that doesn't work right everytime. Gives the right output sometimes tough. Here is what i did:
import random
def normal_search(l, target):
# printing the list
l1 = l
x = ' '.join([str(l)])
print(f'The list is {x}')
choose = random.choice(l)
if choose == target:
index = l.index(choose)
index += 1
print(f"I found it! It's {index}. element.")
while choose != target:
l.remove(choose)
choose = random.choice(l)
print(choose)
index = l1.index(choose)
index += 1
print(f"normal_search I found it! It's {index}. element.")
# creating a shuffled list of 0 to 10
a = []
n = 0
while len(a) < 10:
n += 1
a.append(n)
random.shuffle(a)
normal_search(a, 5)
I am trying to get the target as output. What is making the output wrong?
I think the error is due to the fact that every time it does not find the target element the list decreases by 1 and if the removed element is before the target element it will change index.
I think the only solution is to stop removing the wrong elements, this would guarantee the correct functioning of the program but would increase its execution times.
import random
def normal_search(l, target):
# printing the list
x = ' '.join([str(l)])
print(f'The list is {x}')
while True:
choose = random.choice(l)
if choose == target:
index = l.index(choose)
index += 1
print(f"normal_search I found it! It's {index}. element.")
break
# creating a shuffled list of 0 to 10
a = list(range(10))
random.shuffle(a)
normal_search(a, 5)
As #FraRomee said, you are removing one element every step, suppose at first you have a list like: [0, 6, 4, 2, 3, 5, 1, 8, 9, 7], and index(5) is 6 and you randomly choose an element: 3 and it is not equal to 5 and you remove it, then you have [0, 6, 4, 2, 5, 1, 8, 9, 7] and length of list is 9 and index(5) is 5
and so on you choose 6 and remove it and you have [0, 4, 2, 5, 1, 8, 9, 7].
so if this time you select 5 correctly, index is 4 and it is correct for new list but is wrong for initial list and you cant use it for your own.
my code points:
you can create a list from a to b using list(range(a,b+1)) and you don't need while loop.
you can choose all elements from first in while body using break statement. if condition is False, so break loop, if not, go on and choose a new element.

Python find index of last element smaller than number

I have a list of numbers from 0 to 3 and I want to remove every number that is smaller than 2 xor is not connected to the last 3 in the list. It is also going to be done about 200 Million times so it should preferably perform well. For example, I could have a list like that:
listIwantToCheck = [3, 0, 1, 2, 0, 2, 3, 2, 2, 3, 2, 0, 2, 1]
listIWantToGet = [2, 3, 2, 2, 3]
I already have the index of the last 3 so what I would do is:
listIWantToGet = listIWantToCheck[??? : indexOfLastThree + 1]
??? being 4 in this instance. It is the index with the mentioned conditions.
So How do I get the index of the last number smaller than 2?
Nailed it, the index i want is
index = ([0]+[i for i, e in enumerate(listIWantToCheck[:indexOfLastThree]) if e < 2])[-1] + 1
List comprehension is truly beautiful.
I enumerated through the slice and created a list of all indices, which point to a number smaller than 2 and took the last. The 0 in front is added to circumvent an index error, which would occur if there are no elements smaller than 2.
So if i get this right you want to get the index of the last number smaller than 2 that comes before the last 3.
My approach would be to take the part of the list from index 0 to the index of the last 3 and then reverse the list and check if the number is smaller than 2.
If you however want to get the last 2 of the entire list just reverse it and loop through it the same way
for i in listIWanttoCheck[0:indexOfLastThree].reverse():
if i <2:
return listIWanttoCheck.index(i)
Correct me if I missunderstood your problem

Strange behavior observed when iterating over list in python

I has a small question,
Let me share a small snippet of code
num = [1, 2, 3, 4]
for i in num:
print(i)
num[2] = 5
here the output is
1
2
5
4
the iterator's value got updated to 5 instead of 3 in the 3rd iteration, now if I do this
num = [1, 2, 3, 4]
for i in num:
print(i)
num = [5 if j == 3 else j for j in num]
the output is
1
2
3
4
the iterator stayed the same this the 3rd iteration
Does anyone know the reason for this behavior?
(I observed this in Python 3.8 or 2.7)
When you run the for loop, it takes the id of the provided object and iterates over it.
In the first code snippet, you are changing an element of the original object, so when the iterator reaches the second element it takes the updated value.
However, in the second case you are creating a new object with different values, but the object that you provided to the loop stays the same.
A way of checking this behaviour is to get the id of the variable before and after the modifications, and see how it does not change in the first case but it changes in the second case:
my_list = [1, 2, 3]
original_id = id(my_list)
# Check if the object identification changes after modifying one element
my_list[2] = 4
new_id = id(my_list)
if original_id == new_id:
print("1st case: The ID stays the same")
else:
print("1st case: The ID has changed")
# Check now what happens if you create a new list
my_list = [3, 2, 1]
new_id = id(my_list)
if original_id == new_id:
print("2nd case: The ID stays the same")
else:
print("2nd case: The ID has changed")
The obtained result is the following:
1st case: The ID stays the same
2nd case: The ID has changed
In your first code, your num[2]=5 replaces values in first loop instance itself, so 5 is printed in the normal loop.
Your second code:
It's actually replacing and only i is printed in second code.
You need to print num to check the replaced value.
Code:
num = [1, 2, 3, 4]
for i in num:
print(i)
num = [5 if j==3 else j for j in num ]
print (num)# This line
Output:
1
2
3
4
[1, 2, 5, 4]
The for loop already gets an iterator of num, and while inside loop you modify num, then the for loop does not look again to num, and iterates using the old list.

why the swapping does not take place when indices are 0 and 1?

I have an unordered array consisting of consecutive integers [1, 2, 3, ..., n] without any duplicates. It is allowed to swap any two elements. I need to find the minimum number of swaps required to sort the array in ascending order.
Starting from the first element of the list, I try to put them in their right position (for example if the first element is 7 it should be in the 6th position of the list). To go one by one in the list, I make a copy, and do the swapping in the second list.
a = [4,3,1,2]
b = a[:]
swap = 0
for p in a:
if (p!= b[p-1]):
b[p-1], b[b.index(p)] = b[b.index(p)], b[p-1]
swap+=1
print(swap)
this code works, except for the case that I have to swap two elements in the list whose position is either 0 or 1, in this case . which I don't understand why?? since I'm not exceeding the limit.
Can anyone please explain to me why this happens?
For example, if I print p, two indices where swapping happens, updated list of b and updated number of swaps:
p = 4
idx1= 3 idx2= 0
b= [2, 3, 1, 4]
swap = 1
p = 3
idx1= 2 idx2= 1
b= [2, 1, 3, 4]
swap = 2
p = 1
idx1= 0 idx2= 1
b= [2, 1, 3, 4]
swap = 3
p = 2
idx1= 1 idx2= 0
b= [1, 2, 3, 4]
swap = 4
In this case, you can see that for p = 1, when indices are 0 and 1, the swapping is not taking place.
I changed the order of b[p-1], b[b.index(p)] and I don't have the same problem anymore, but I don't understand the reason.
I have encountered the same problem before, and stucked for a while. The reason to cause this is the order of multiple assignment.
b[p-1], b[b.index(p)] = b[b.index(p)], b[p-1]
Actually multiple assignment is not exactly assign at the same time. pack and unpack mechanism behind this. so it will change b[p-1] first, and b.index(p) in b[b.index(p)] will be find a new index which is p-1 when the case p=1 idx1=0 idx2=1
if you change the assignment order, it will work fine.
b[b.index(p)], b[p - 1] = b[p - 1], b[b.index(p)]
or calculate idx first:
idx1, idx2 = p - 1, b.index(p)
b[idx1], b[idx2] = b[idx2], b[idx1]
I recommend the second version, because first version will do index twice. cost twice time than second version.
you can refer to my related question here: The mechanism behind mutiple assignment in Python
by the way, I think your algorithm is inefficient here, to decrease swap time, but use O(n) index operation, and also copy a array here. I think you can use the same idea, just swap in orignal array.

Get the pairs of values from a list according to a condition without elements repeating

I have a list of integers like:
1 3 4 4 9 7 10 (the number of elements is between 1 and 200000)
and an integer variable D, it lies between 0 and 10^9.
Let it be 5 for example.
I need to count how many pairs in the list have a difference between each other not bigger than a variable D but the tricky part is that if I took the zero element with value 1 and the first element with the value 3(the difference between them meets the condition) I can't use these elements of a list again.
For example for the sequence above the answer is 3 pairs: (1,3) (4,4) (7,9)
I wrote a code which seems to be correct but I need a hint how to change the input sequence and the variable d the way it will output wrong answer
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
i = 0
while True:
if i >= len(list_of_colors):
break
if i != len(list_of_colors) - 1:
# if the number i in list and i+1 is the same or difference between them not greater than a variable d...
if (int(list_of_colors[i]) == int(list_of_colors[i + 1])) or abs(int(list_of_colors[i]) - int(list_of_colors[i + 1])) <= d:
#print list_of_colors[i]," ",list_of_colors[i + 1]
number_of_pairs += 1 # increasing the number of the acceptable pairs
i += 2 # jump over two elements, we already counted them
continue
i += 1
print number_of_pairs
I need another algorithm to compare it with the results of my algorithm on the various range of the input sequence and the variable d
Suggest your ideas please
I have a greedy solution for this problem:
Sort the input sequence.
Parse the sorted sequence as follows:
For ith element in the sequence,
if |a[i+1]-a[i]| <= D,
then pair up the elements. Proceed to process i+2th element.
else
proceed to process i+1th element.
My solution here is to first "clean" the list what means I made the number of elements even. Then I've converted the list into a list of tuples (pairs).
My result for this example is 3 pairs in order to your condition.
list_of_colors = [1, 3, 4, 4, 9, 7, 10]
d = 5
number_of_pairs = 0
list_of_colors.sort() # the values in the list are not always sorted
# remove the last element if the number of elements is odd
if len(list_of_colors) % 2 != 0:
list_of_colors = list_of_colors[:-1]
# create a list of tuples
list_of_colors = [tuple(list_of_colors[i:i+2]) for i in range(0, len(list_of_colors), 2)]
for i in list_of_colors:
if (int(i[0]) == int(i[1])) or abs(int(i[0])) - int(i[1]) <= d:
number_of_pairs += 1
print number_of_pairs

Categories

Resources