Python: Comparing values in two lists - python

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

Related

Find occurrence of a string in another string

Details:
There are two strings x and y.
Count the number of occurrence of y in x as follows:
Length of y is 3.
Increment the "count" value when y == x[i] x[i+2] x[i+4]
Example:
x = "aabbcc"
y = "abc"
output: 2
My Code:
def solution(x, y):
i, count = 0, 0
j = i + 2
k = i + 4
while i+4 < len(x):
cur = x[i]
while i < len(x) and i != j:
i += 1
while i < len(x) and i != k:
i += 1
count += 1
return count
solution(x, y)
I am getting count = 1. It should give count = 2
There's a couple of logic errors in your code.
The problem happens here:
while i < len(x) and i != j:
i += 1
res.append(x[i])
You keep increasing i until it is either len(x) or greater, or until it is the same as j. But since you set j to be 2 at the start (and never update it), it will simply end up setting i to len(x). And x[i] will thus fail, since x[len(x)] tries to index an element just outside x.
However, there's a few more remarks to make:
you collect what you find in res, but really only want a number (e.g. 2) as a result
you define count but don't use it
you track the coordinates in the string in three separate variables (i, j, k) and have a lot of logic to increment the first, but really all you need is to step through the string one position at a time, and look at the offsets directly
Given all that and the problem description, you were probably going for something like this:
x = "aabbcc"
y = "abc"
def solution(x, y):
i, count = 0, 0
while i + 4 < len(x):
if (x[i], x[i+2], x[i+4]) == (y[0], y[1], y[2]):
count += 1
i += 1
return count
print(solution(x, y))
However, Python has some cleverness that would make it even simpler (or at least shorter):
def solution(x, y):
count = 0
for i in range(len(x)-4):
if x[i:i+5:2] == y: # slicing with a stride of two, instead of direct indexing
count += 1
return count
Or even:
def solution(x, y):
return len([x for i in range(len(x)-4) if x[i:i+5:2] == y])
But that's favouring brevity over readability a bit too much, I feel.
A generator expression solution, taking advantage of True/False == 1/0 in a numeric context:
def solution(x, y):
return sum(y == x[i:i+5:2] for i in range(len(x)-4))
Increment the "count" value when y == x[i] x[i+2] x[i+4]
This is the same as simply creating the string consisting of x[0], x[2], x[4]... (every even-numbered character) and the string consisting of x[1], x[3], x[5]... (every odd-numbered character); counting the occurrences of y in each; and adding those two results together.
Creating the strings is trivial, and a common duplicate. Counting occurrences of a substring is also well-trodden ground. Putting these tools together:
def spread_substrings(needle, haystack):
even_haystack = haystack[::2]
odd_haystack = haystack[1::2]
return even_haystack.count(needle) + odd_haystack.count(needle)

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

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

Python for loop to iterate two times

Below is example code:
List1 = [['a'], ['b'], ['c']]
range_value = len(List1) * 2
for x in range(0, range_value):
if x == 0 or x == 1:
for y in List1[1]:
print y
if x == 2 or x == 3:
for y in List1[2]
if x == 4 or x == 5:
for y in List1[2]
This is manual steps defineing if statement in case I have big values like 100 or 1000. Its difficult, Please help me with any logic for this. first two values should use List[1] and next two values List[2] and so on.
Use a third loop:
for x in List1:
for _ in [0,1]:
for y in x:
...
This iterates over each element of List1 twice, as in the original code, without explicit index wrangling.
I think you're looking for:
for y in List1[x//2]
It's a bit hard to tell, since you started at index 1 instead of index 0, but apparently want to use every element of the list. You may need [x//2 + 1].
Another possible enhancement is to double-step your outer loop:
for x in range(0, range_value, 2):

Combining two lists into one list where they share the same values and removing duplicates using list comprehensions

I am trying to combine two lists:
One holds Square numbers.
The other stores Pentagonal Numbers.
def pentaSquares():
l = []
n = 0
squares = lambda x: [x*x for x in range(n)]
penta = lambda y: [y*(3*y-1)//2 for y in range(n)]
while l.index < 4:
l = [i for i in squares for j in penta if squares == penta]
n = n+1
return l
I must merge these lists using List Comprehensions where their values match until there are 4 elements in the list.
If somebody could point me in the right direction, that would be much appreciated.
I am currently getting this error: TypeError: unorderable types: builtin_function_or_method() < int()
Using a pair of generators should give you this answer without taking up all the memory in the world. This should work nicely (though perhaps take a very long time) for any resultant list size.
import itertools
squares = (x*x for x in itertools.count(0))
pentas = (y * (3*y-1) // 2 for y in itertools.count(0))
results = []
cur_s, cur_p = next(squares), next(pentas)
# prime the pump
while len(results) < 4:
if cur_s == cur_p:
results.append(cur_s)
# success
# advance the generator with the smaller current result
if cur_s > cur_p:
cur_p = next(pentas)
else:
cur_s = next(squares)
There's no reason to use list comprehensions for this task, but if you had to you should use the list -> set and set intersection approach in cricket_007's now-deleted answer
for n in range(itertools.count(0)):
squares = [x * x for x in range(n)]
pentas = [y * (3*y-1) // 2 for y in range(n)]
result = set(squares).intersection(set(pentas))
if len(result) >= 4:
break
def pentaSquares(n):
squarlist=[x*x for x in range(n)]
pentalist=[y * (3*y-1) // 2 for y in range(n)]
l=[x for x in squarlist if x in pentalist]
return l
>>> pentaSquares(10000)
[0, 1, 9801, 94109401]
EDIT 1 O.P Satisfaction
def pentaSquares(n):
squarlist=[]
pentalist=[]
squares = lambda x:x*x
penta = lambda y:y*(3*y-1)//2
for i in range(n):
squarlist.append(squares(i))
pentalist.append(penta(i))
l=[x for x in squarlist if x in pentalist]
if l < 4:
print('there are less than 4 values, input larger n')
return l

Categories