Inserting values into list - python

I am trying to insert values in a list which is part of while loop, instead of inserting the last value is replacing the one before, so the list will always have only one value!, I am trying to add the values not replacing them, here is my code:
while X != 1:
resultList = [];
#extList = []
count += 1
if X % 2:
X = 3 * X + 1
elif not X % 2:
X = X // 2 #important to use double slash to have a integer division
print(X)
resultList.insert(count-1, X)
#print("the resultList is " + str(resultList))
#extList.extend(resultList)
print("The inputValue "+str(originalValue)+" took "+str(count)+" calculations to reach 1")
print (resultList)
any help is appreciated

On each iteration of while loop you creates new instance of resultList list.
while X != 1:
resultList = [];
...
should be replaced with
resultList = [];
while X != 1:
...
And to add new element to the end of list you could use append method. Like
resultList = [];
while X != 1:
if X % 2:
X = 3 * X + 1
else:
X = X // 2 #important to use double slash to have a integer division
print(X)
resultList.append(X)

The problem is here:
while X != 1:
resultList = [];
#etc
You are re-creating the list with every iteration of the loop. Hence, it will only have one value at the end, the one given by the only insert in the final iteration.
Taking the assignment out of the loop like so:
resultList = [];
while X != 1:
#etc
..fixes the problem.
An additional note, what you have done here is unnecessary:
elif not X % 2:
X = X // 2
You needn't repeat and invert your original condition. You can simply make it an else.
if X % 2:
X = 3 * X + 1
else:
X = X // 2

Related

Python: Comparing values in two lists

I've really tried looking all over for solutions to my problem but haven't been successful in finding anything. If someone else has already asked this question, I apologize. Onto the problem.
I have two lists in with values to be compared to each other. I have tried the following option.
list1 = [1,3,5,7,9]
list2 = [200,2]
x = 0
n = 0
y = 0
while x <= 9:
if list1[y] >= list2[n]:
print('TRUE')
x = x + 1
y = y + 1
if y > 4:
y = 0
n = n + 1
else:
print('FALSE')
x = x + 1
y = y + 1
if y > 4:
y = 0
n = n + 1
The only problem is, instead of the variables in place, I need to iterate through a list of values.
So instead, I would like the code to look something like this:
x = 0
n = [0,1]
y = [0,3]
z = len(n) + len(y) - 1
while x <= z:
if list1[y] >= list2[n]:
print('TRUE')
x = x + 1
else:
print('FALSE')
x = x + 1
Where n and y are index values of the numbers that I want to compare.
This does not work for me and I'm really not sure how else to do this.
Edit: I didn't think I had to explain everything by text since I included two sets of code. The first set of code works and it shows exactly what I am trying to do. The second is what I want it to do.
Broken down further I want to know if list1[0]>=list2[0], followed by list1[3]>=list2[0], followed by list1[0]>=list2[1], followed by list1[3]>=list2[1]. The outputs that I expect are in the code I provided.
Apologies if I wasn't clear before. I need to call specific index positions that I will have in a separate list. This is the problem that I tried to outline in the second code.
I think now get what you are trying to do.
First, there are two lists of "raw" data:
list1 = [1,3,5,7,9]
list2 = [200,2]
Then, there are two sets of "indices of interest":
y = [0, 3] # indices of interest for list1
n = [0, 1] # indices of interest for list2
I think the following can achieve what you want:
product = [(index1, index2) for index2 in n for index1 in y] #cartesian product
for index1, index2 in product:
if list1[index1] >= list2[index2]:
print("True")
else:
print("False")
Or if the cartesian product is not wanted, simply do it within nested loops:
for index2 in n:
for index1 in y:
if list1[index1] >= list2[index2]:
print("True")
else:
print("False")

Reverse a specific slice of a list in Python

I am trying to write a function that will receive a list and will return a list containing inverted elements between even and odd index. For example:
IP : [1,2,3,4]
OP : [2,1,4,3]
I don't understand why I get an IndexError: list index out of range error with the following code:
def mixed(list):
x = 0
y = 2
l = []
for element in list:
mod_list = list[x:y]
l.append(mod_list[1])
l.append(mod_list[0]
x += 2
y += 2
return l
The l.append(mod_liste[1]) seems to be the issue...
You can use built-in functions and slicing for that:
from itertools import chain
L = [1,2,3,4]
list(chain(*zip(L[1::2],L[::2]))) # [2,1,4,3]
If you don't want to use build-in function. Just make your loop stop when y is greater than list length. Make check for odd list.
def mixed(list):
x = 0
y = 2
l = []
for element in list:
mod_list = list[x:y]
l.append(mod_list[1])
l.append(mod_list[0])
x += 2
y += 2
if y > list.__len__() and list.__len__()%2 == 0:
break
elif y > list.__len__() and list.__len__()%2 != 0:
l.append(list[y-2])
break
return l

Remove triplets of adjacent numbers from the list [duplicate]

This question already has answers here:
Write a function lines(a) that determines how many balls will be destroyed
(6 answers)
Closed 2 years ago.
Here is the problem. The input is a list of integers. If three adjacent numbers appear next to each other they should be dropped and the operation goes again. Iphone app with the balls of the same colors. The output should be the count of the balls that will be destroyed.
Example:
input = [3,3,4,4,4,3,4]
1st iteration
output: [3,3,3,4]
Final output:
6
4,4,4 on the first iteration, so three balls. and 3,3,3 on the second. Overall six.
My code is below. It will remove the 4,4,4 but will fail after, because list index will quickly go out of range.
def balls(a):
curr_index = 0
removed_count = 0
while len(a) > 2:
if (a[curr_index] == a[curr_index+1]) and (a[curr_index] == a[curr_index+2]):
a.remove(a[curr_index])
a.remove(a[curr_index+1])
a.remove(a[curr_index+2])
curr_index += 1
removed_count += 3
return removed_count
a = [3, 3, 4, 4, 4, 3, 4]
print(balls(a)) # should print 6
Any ideas?
input_values = [3,3,4,4,4,3,4]
values = input_values
while len(values) >= 3:
for x in range(0,len(values)-2):
# if we find 3 values in ar row
if values[x] == values[x+1] and values[x] == values[x+2]:
# update values by cutting out the series
values = values[:x] + values[x+3:]
# break this for loop
break
else:
# for loops can have an else statement
# this means that we came at the end of the for loop
# this if we didn't break the loop (and didn't found a valid triple)
# then we brea
break
#result - amount of removed balls
values, len(input_values) - len(values)
A more generic approach where you can define N
(it will find exact N values)
input_values = [3,3,4,4,4,4,3,3,4]
# amount of neighbours
N = 4
values = input_values
# keep looping as long as we've N values
while len(values) >= N:
# we need this if we break the inner loop
stop = False
# loop over values from left to right
# 3 -> 3 -> 4 -> 4 -> ... until -N + 1
# because that is the last spot that we've N values left
for x in range(0, len(values) - N + 1):
# scout for the next numbers (x+1 x+2 x+3 ....)
# this goes from, x+1 until the end of the serie
# also start counting from 2 - because
# if we've a single match, 2 numbers are equal
for e, y in enumerate(range(x+1, len(values)), start=2):
# if x and y are different, the stop this scouting
# remember y = x+1 x+2 x+3 ....
if values[x] != values[y]:
break
# if we reached this stage, we know that
# x and x+1 x+2 ... are equal
# but also check if we've enough matches
if e == N:
# update values by cutting out the series
values = values[:x] + values[y+1:]
stop = True
break
if stop:
break
else:
# for loops can have an else statement
# this means that we came at the end of the for loop
# this if we didn't break the loop (and didn't found a valid triple)
# then we brea
break
values, len(input_values) - len(values)
Here is one way to do it:
your_list=[3, 3, 4, 4, 4, 3, 4]
def remove_one(l):
if len(l)>2:
for i in range(len(l)-2):
if l[i]==l[i+1]==l[i+2]:
res.extend(l[i:i+3])
l=l[:i]+l[i+3:]
return l
return []
res=[]
while len(your_list)>2:
your_list=remove_one(your_list)
print(len(res))
Output:
6
An approach with a minimal threshold
input_values = [3,3,4,4,4,4,4,3,3,4]
# threshold
N = 3
values = input_values
while len(values) >= N:
# we need this if we break the inner loop
stop = False
# loop over values
for x in range(0, len(values) - N + 1):
# scout for the next numbers (x+1 x+2 x+3 ....)
for e, y in enumerate(range(x+1, len(values)), start=2):
# check if the values of x and x+1 (x+2 x+3 ...) are different
if values[x] != values[y]:
# if so, check if we've reached our threshold of N
if e >= N:
# if this is the case update values by cutting out the series
values = values[:x] + values[y:]
stop = True
break
# if x+n != x then we break this scouting loop
break
# stop is True, this means, that we found N neibouring numbers
# thus we can break this loop, and start over with a new* value
if stop:
break
else:
# for loops can have an else statement
# this means that we came at the end of the for loop
# thus if we didn't break the loop (and didn't found a valid triple)
# then we break
break
values, len(input_values) - len(values)
There are a couple of issues with your code.
The first is you're trying to iterate over the list a single time, but that won't work for your example.
The second is you're assuming the list will always reduce to less than 3, which won't be the case if you have more numbers.
There are also some places you can simplify the syntax, for example:
if (a[curr_index] == a[curr_index+1]) and (a[curr_index] == a[curr_index+2]):
is equivalent to:
if a[curr_index] == a[curr_index + 1] == a[curr_index + 2]:
And
a.remove(a[curr_index])
a.remove(a[curr_index+1])
a.remove(a[curr_index+2])
is equivalent to:
del a[curr_index: curr_index + 3]
So here is one way to accomplish this, thought there are more efficient ways.
def balls(a):
removed = 0
complete = False
# Run until complete is set or the list is too short for a match
while not complete and len(a) >= 3:
for idx, val in enumerate(a):
if val == a[idx + 1] == a[idx + 2]:
del a[idx: idx + 3]
removed += 3
break # Restart every time we find a match
# If it's the last possible match, set complete
if idx == len(a) - 3:
complete = True
break
return removed
I'm little bit late, but my idea is to do the processing in one pass. The idea is that when you drop a tripple, go back two positions to re-check if a new tripple has been created by that change.
Example:
3 3 4 4 4 3
^--- tripple found here, remove it
3 3 3
^--- move the cursor 2 positions left and continue checking
The code:
def drop3(lst):
# drop3 destroys the lst, make a copy if you want to keep it
dropped = 0
cursor = 0
limit = len(lst) - 2
while cursor < limit:
if lst[cursor] == lst[cursor+1] == lst[cursor+2]:
del lst[cursor:cursor+3]
cursor = max(0, cursor-2)
limit -= 3
dropped += 3
else:
cursor += 1
return dropped
A linear-tme solution:
def balls(a):
b = []
for x in a:
b.append(x)
if b[-3:] == [x] * 3:
del b[-3:]
return len(a) - len(b)

Using variable to call element of list is returning "List index out of range"

I'm new to coding and have been having this problem for a bit, I've tried looking around and messing with the code but can't seem to find the problem as simple as the solution probably is.
My code is:
import random
import sys
import os
clear = lambda: os.system('cls')
clear()
filt = int(raw_input("What number do you want your results to be filtered by?"))
clear()
gorl = raw_input("Do you want to filter numbers greater or lower than %i?" %(filt))
clear()
ammvar = int(raw_input("How many variables do you want to filter?"))
clear()
y = ammvar
var_list_remainder = []
var_list = []
varnum = 1
while ammvar > 0:
var_list.append(int(raw_input("Variable %i:"%(varnum))))
varnum = varnum + 1
ammvar = ammvar - 1
clear()
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
if gorl == "greater":
x = 0
while y > 0:
if var_list[x] > filt:
var_list_remainder.append(var_list[x])
x = x + 1
y = y - 1
elif var_list[x] <= filt:
x = x + 1
y = y + 1
elif gorl == "lower":
x = 0
while y < 0:
if var_list[x] > filt:
var_list_remainder.append(var_list[x])
x = x + 1
y = y - 1
elif var_list[x] >= filt:
x = x + 1
y = y + 1
print(var_list_remainder)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
If I run this and I get to input my variables then the following error occurs:
Traceback (most recent call last):
File "c:/Users/D/OneDrive/Documents/Intro To Python/GreaterOrLower.py", line 43, in
if var_list[x] > filt:
IndexError: list index out of range
The problem is you're trying to use y as an auxiliary variable to iterate through the list var_list (since it tells the loop when to stop) and it's not stoping the loop on time. I would change the way you iterate through var_list and use a simpler approach.
I only changed this bit of code:
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
if gorl == "greater":
for item in var_list: # item will take the value of each element in the list for each iteration
if item > filt: # we check if the item is greater
var_list_remainder.append(item) # we append it
elif gorl == "lower":
for item in var_list: # item will take the value of each element in the list for each iteration
if item < filt: # we check if the item is lower
var_list_remainder.append(item) # we append it
print(var_list_remainder)
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
I would change a few more things but those are not related to question.
Because y can be incremented, the while loop can run more than ammvar, thus x can grow bigger than the size of the list. When getting an item by an index bigger than the size of the list (minus one, because it is zero indexed) you get an exception.
Your algorithm is not clear enough to me for me to fix it.

List returns more values than expected

I have a list of say two values, I'm then supposed to multiply each value by an integer until both elements in become integers and append these new values to a new list. Say I have a list [0.5,1], what's supposed to happen is that I'm gonna multiply each by 2 and get 1 and 2 and append these to a new list [1,2]. For the code I've written, I get four values(!) in my new list when I'm just supposed to get two, where in the code lies the error?
u=1
newlist = [1, 0.5]
alist = []
while True:
cont = True
for value in newlist:
w = value*u
rounded = round(w)
alist.append(rounded)
if not (abs(rounded - w)<=0.1):
cont = False
if cont:
break
u+=1
It looks like you should be clearing alist inside of the while loop, otherwise each run through the for loop will append len(newlist) items to alist without removing previous elements of alist.
u = 1
newlist = [1, 0.5]
while True:
alist = []
cont = True
for value in newlist:
w = value*u
rounded = round(w)
alist.append(rounded)
if not abs(rounded - w) <= 0.1:
cont = False
if cont:
break
u += 1
>>> alist
[2.0, 1.0]
The reason why you're getting four values is because you're using the same list over the course of several loops, and you keep adding elements to that same list. Besides that, there are a couple of errors in your code, I think it's simpler if I show you a working version and you figure them out:
u = 1
newlist = [1, 0.5]
alist = []
while True:
cont = True
alist = []
for value in newlist:
w = value*u
if int(w) != w:
cont = False
break
alist.append(int(w))
if cont:
break
u += 1
I'm kindof having trouble following your code, here, this is how you could do it:
vals = [1,0.5]
i=1
while 1:
if (vals[0] * i) % 1.0 == 0:
if (vals[1] * i) % 1.0 == 0:
print i
vals[0] = vals[0]*i
vals[1] = vals[1]*i
print vals
break
i+=1
Using functions can make things easier to understand. Here's one attempt.
def nearly_int(x):
return abs(x - round(x)) < 0.1
def find_multiple(a, b):
u = 1
while not nearly_int(a * u) or not nearly_int(b * u):
u += 1
return [round(a * u), round(b * u)]
newlist = [1, 0.5]
alist = find_multiple(*newlist)

Categories