Reverse a specific slice of a list in Python - 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

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")

Unable to Solve 'list index out of range' error

I am trying to create a function that counts the number of prime numbers for a given range and I receive a list index out of range error on the commented line below and cannot figure out what is wrong.
def count_primes(num):
my_list = list(range(2,num+1))
for i in my_list:
x = my_list[i] # This line
y = not x
r = x%y if y != 0 else 0
z = []
if x%1 == 0 and x%x == 0 and r != 0:
z.append(x)
return len(z)
When you iterate over the list with for i in list, i variable contains items of the list and not its indexes.
Your list contains numbers [2, 3, 4,.. num]. And the max index in it is num-2. So when you try to refer to list[num-1] or list[num] you get this error.
The solution is to remove the line in bold and use x instead of i in for loop statement: for x in list.

Find first non zero numbers in an array (zeroes can be anywhere)

Suppose we have an array: x = [10,0,30,40]. I would like to extract the first non zero element and store it in a different variable, say y. In this example, y = 10. We can also have many zeros, x = [0,0,30,40], which should give y = 30 as the extracted value.
I tried a Python snippet like this:
i = 0
while x[i] != 0:
y = arr[i]
if x[i] == 0:
break
This only works if the array is [10,0,30,40]. It does not work if I have 0,20,30,40. The loop would stop before that. What is an efficient way to implement this? I try not to use any special Numpy functions, just generic common loops because I might need to port it to other languages.
You can do this
x = [10,0,30,40]
for var in x:
if var != 0:
y = var
break
You could use list comprehension to get all the non-zero values, then provided there are some non-zero values extract the first one.
x = [10,0,30,40]
lst = [v for v in x if v != 0]
if lst:
y = lst[0]
print(y)
The problem with your code is that you don't increment i so it's stuck on the first element. So what you could do to keep the code portable is:
while x[i] != 0:
y = x[i]
if x[i] == 0:
break
i+=1
This code is still not clean, because if there is no 0 in your array then you will get an IndexError as soon as you reach the end.
I'm kind of new to this but i think this should work:
x = [0, 12, 24, 32, 0, 11]
y = []
for num in x:
if num != 0:
y.append(num)
break
print(y)
You can use the next function:
x = [10,0,30,40]
next(n for n in x if n) # 10
x = [0,0,30,40]
next(n for n in x if n) # 30
if you need to support the absence of zero in the list, you can use the second parameter of the next() function:
x = [0,0,0,0]
next((n for n in x if n),0) # 0

TypeError: string indices must be integers..what is the problem

i'm getting TypeError: string indices must be integers... how can i solve this?
And the code is:
def myfunc(x):
y=''
for i in x:
y=y+x[i].upper() +x[i+1]
i+=2
return y
Try to avoid iterating over indices when possible. You can do that there by iterating over x zipped with its own tail:
def myfunc(x):
y = ''
for x1, x2 in zip(x, x[1:]):
y = y + x1.upper() + x2
return y
Even better (and more efficient), you can use join to create y from one list.
import itertools
def myfunc(x):
return ''.join(list(itertools.chain.from_iterable(x1.upper() + x2 for x1,x2 in zip(x, x[1:]))))
You should index x iterating over the actual indices of x, not its values, thus doing range(len(x)), or enumerate(x). Also you cannot modify the iterator in a for loop, you need a while if you want to do so:
def myfunc(x):
y=''
i = 0
while i < len(x) - 1:
y=y+x[i].upper() +x[i+1]
i+=2
return y
When you say: for i in x: is it like you are saying "for each letter in the x string", so at every iteration, i will be the next letter from the string. You can create a simple loop like you have with a print i statement to see the behavior.
Another problem with your code is the x[i + 1] statement. When the for loop will reach the last iteration, you'll try to access something non-existent and you'll get an IndexError. This being said, you should modify your code like this:
def myfunc(x):
y = ''
for i in range(0, len(x) - 1, 2):
y = y + x[i].upper() + x[i + 1]
return y
Because you want to iterate every other character, I also used another set of parameters for range: range([start], stop[, step]).
start: Starting number of the sequence.
stop: Generate numbers up to, but not including this number.
step: Difference between each number in the sequence.
Cheers!
You can do that with enumerate:
Code:
x = 'abcdef'
def myfunc(x):
y = ''
c = 0
for i, j in enumerate(x):
if i == c:
y += j.upper()
else:
y += j
c += 2
return(y)
assert myfunc(x) == 'AbCdEf'
print(myfunc(x))
Output:
AbCdEf

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