How to compare with .index cell by cell in python - python

Y = [1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1,]
X = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 ]
Di = []
for number in Y: # as for each number in Y
if number > 0: # and the number if more than 0
if number in X: # compare to the numbers in X
if number not in Di: # when in cases of number found not in X
Di.append(number) # Add to the Di
print("Di",Di) #print the letters Di and the value of the number 1 found
if Di == [1]: # Condition #if the value is equal to 1 print excluded
print("excluded") # Clause #print excluded
else:
print("not excluded")
Output
Di --> excludeed #because of digit 5 counting 0
The above code is from a python program that try to compare the 1 or 0 where it works as follow find the first value that is 0 in Y list and compare it with the value in the same position in the list X and if found positive exclude if not found negative go to the next 0 in the list Y and so on when the list is finished and could not exclude any print not excluded. hope this make sense but it is not doing its Function. if someone can modify it for me with .index to make the expected function this would make my life much happier.
kind regards
Basem

Y = [1, 1, 0, 1, 0]
X = [0, 0, 1, 0, 0]
def excluder(yVal, xVal):
for count, ele in enumerate(yVal):
print("Current Y list value in this loop cycle:" + str(ele))
if yVal[count] > xVal[count]:
print(str(yVal[count]), " is greater in the Y list")
elif yVal[count] < xVal[count]:
print(str(xVal[count]), " is greater in the X list")
else:
print(str(xVal[count]), " X and Y are equal")
excluder(Y, X)
Output below....I included an enumerate function because it is a good way to get the count in a loop without having to increment a variable.
Current Y list value in this loop cycle:1
1 is greater in the Y list
Current Y list value in this loop cycle:1
1 is greater in the Y list
Current Y list value in this loop cycle:0
1 is greater in the X list
Current Y list value in this loop cycle:1
1 is greater in the Y list
Current Y list value in this loop cycle:0
0 X and Y are equal

Related

Check if a Python list has X number of consecutive values equal to Y

I have a collection of lists each containing 16 items, and I want to find lists with 12 consecutive values either > or < than a specified threshold. For now, I have iterated through the lists and put 1 for values greater and -1 for values less than the threshold, and I used to following to eliminate those that don't have 12 of either.
if list.count(-1) >= 12 or list.count(1) >= 12:
How do I efficiently check for 12 consecutive values? (12 values can loop around) for example this would count
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1]
Currently I have 2 nested for loops, but I know this checks the same value multiple times.
for i in range(16):
light = 0
dark = 0
for j in range(12):
index = i + j
if index > 15:
index -= 15
if list[index] == 1:
light += 1
elif list[index] == -1:
dark += 1
else:
break
if dark > 0 and light > 0:
break
if dark == 12 or light == 12:
return True
I would harness itertools.groupby following way
import itertools
data = [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1]
runs = [len(list(g)) for _,g in itertools.groupby(data)]
if data[0] == data[-1]:
runs[0] += runs.pop()
print(max(runs) >= 12) # True
Explanation: I use itertools.groupby to get length of runs (in this case [7,4,5]) - itertools.groupby does group only adjacent equal elements, then if first and last values of data are equal I extract last element from runs and add it to first element (as you allow wraparound), then I check if longest run is equal or greater 12.
If I've understood correctly what you want, then here are some ways to do it:
First off you can sort the list, putting every element in an order, and then doing a linear search and incrementing a counter every time it's the same value with the previous list element
a.sort()
count = 0
for i in range(16):
if count == 12:
break
if a[i - 1] == a[i]:
count += 1
Another way to do it is with the modulo operator, which doesn't require you sorting the list. And you can add some variables to check if you've done a full loop.
flag_count = 0
count = 0
i = 0
while True:
if count == 12 or flag_count == 2:
break
if a[i % 15] == a[(i + 1) % 15]:
count += 1
if i % 15 == 0:
flag_count += 1
i += 1
You can loop through the list while keeping track how many times you've seen a specific value. Everytime you see a different value this counter resets (because you are looking for consecutive values).
def consective_values(input_list, target_value):
i = 0
count = 0
for _ in range(2 * len(input_list)):
if input_list[i] == target_value:
count += 1
else:
count = 0
if count == 12:
return True
i = (i + 1) % len(input_list)
return False
Because the consecutive values can loop around you have to be a bit more careful with the list indexing and the loop variable. The max number of loops is equal to twice the length of the list. When you still haven't found 12 consecutive values at this point you know there aren't any. TO have an index loop around a list you can always apply the modulo (%) operator

How do I write O(n2) program of matrix n x n?

I am practicing and trying to write O(n^2) program that tests whether there are two 1s lying on the same row or the same column in A. Where A = n x n matrix of 0s and 1s.
Given A as:
I should get answer return of 2 matches.
One is on the 1st row, and another on the 3rd column.
My 2nd Attempt:
def testLines():
count = 0
for x in range( 0, len(A)-1 ):
if( (A[x] == 1) & (A[x+1] == 1) ):
count+=1
for y in range( 0, len(A)-1):
if( (A[y] == 1 & A[y+1]) == 1 ):
count+=1
print( count, '1s has been matched in the array A')
testLines()
You want to nest the two loops and change the indexes so that both x and y are parsed. Currently your code moves through (all x, y = 0) and (x = 0, all y).
A = [[0, 0, 1, 1],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 1, 0]]
def testLines():
count = 0
N = len(A)
for x in range(N):
for y in range(N):
if A[x][y] == 1:
if x+1 < N and A[x+1][y] == 1:
count += 1
if y+1 < N and A[x][y+1] == 1:
count += 1
print(count, '1s has been matched in the array A')
testLines()
Alternatively, you can go the Schwarzenegger way and not check if (x+1, y) or (x, y+1) even exist. That will raise IndexErrors that you can choose to ignore.
def testLines():
count = 0
N = len(A)
for x in range(N):
for y in range(N):
try:
if A[x][y] == 1 and A[x+1][y] == 1 or A[x][y+1] == 1:
count += 1
except IndexError:
continue
print(count, '1s has been matched in the array A')
You can run one nested loop (n²) to get summation of rows. If summation is 2 then that row has two 1s.
Now interchange rows and columns(consider rows as columns & vice versa).
Again run nested loop (n²) to check summation of columns.
n²+n²= O(n²)

How to choose specific minimum values in lists and do mathematical operations on them

After getting data from user input I put the input in lists like this:
x= [3, 2, 1, 0, 1, 2]
y= [1, 2, 0, 3, 4, 1]
I have manged to write this as:
rows = 3
weight = 0
high =0
low =0
while rows>=3 and rows<=200:
rows, weight = map(int, input().split())
break
count_input = 0
while count_input<rows:
while high>=0 and low<=100:
high, low = map(int, input().split())
i=i+1
if count_input==rows:
break
To choose the minimum number in a list i tried this:
smallest = None
for number in [1, 0, 3, 4, 5, 2]:
if smallest is None or number < smallest:
smallest = number
print('Smallest:', smallest)
my questions are:
How to determine minimum values in these two lists and add minimum values together BUT taking into account that selected minimum values of same positions like x[0] and y[0], or x[1] and y[1] can not be added together.
Elements in diagonal position to each other like x[0] and y[1], x[2] and y[3] can not be added together
Also How to put a limit for number of chosen values, like choosing the minimum 4 values found in lists together
This is how I would approach finding the minimum of the data set, with the logic for not using values between the lists if they have the same index or a diagonal index
x = [3, 2, 1, 0, 1, 2]
y = [1, 2, 0, 3, 4, 1]
final_min = max(x) + max(y)
for x_index in range(0, len(x)):
for y_index in range(0, len(y)):
if y_index == x_index - 1 or y_index == x_index or y_index == x_index + 1:
pass
else:
test_min = x[x_index] + y[y_index]
if test_min < final_min:
print(test_min) # prints 3, 2, 1
final_min = test_min
print(final_min) # prints 1
This makes sense by visually looking at the data, as there are 3 places that the sum would be 1, and the only place it could be smaller (0) would be 0 + 0 but that is a diagonal pair so it cannot be included. You should keep in mind that this is a computationally expensive approach though because it iterates through the y list for every index in the x list, and if your lists are large this will take a LONG time! Also, if the lists are different lengths then the program will likely hit an IndexError and I have not included safeguards for that. I cannot help you on your final point because I do not understand what is meant by:
How to put a limit for number of chosen values, like choosing the minimum 4 values found in lists together
You would need to clarify for anybody to understand what is meant here.
Use min(..) and index(..).
This solution may not be entirely correct, but you get the idea...
def add_min_with_constraints(a, b):
if len(a) == 0 or len(b) == 0:
return -math.inf
min_a_i = a.index(min(a))
min_b_i = b.index(min(b))
if min_a_i == min_b_i or abs(min_a_i - min_b_i) == 1: # same or diagonal indices
# exclude the current minimums
return add_min_with_constraints(a[:min_a_i] + a[min_a_i+1:],
b[:min_b_i] + b[min_b_i+1:])

Programming Maze Solution recursively

This function is intended to recursively navigate a maze and find the length of the shortest path. The path itself is not necessary, only the length. The maze is represented by a 2d list with values such as
0 1 0 0 0
0 0 0 1 0
0 0 0 1 0
The user starts at (0,0) and must end up at the end of the maze as defined (in my case it is the bottom right cell). 1's represent walls.
def maze(x,y,array,length):
m = len(array)
n = len(array[0])
if x < 0 or y < 0 or x == m or y == n or array[x][y] == 1:
return float("inf")
elif x == m - 1 and y == n - 1:
return length
else:
array[x][y] = 1
up = maze(x - 1,y,array,length + 1)
right = maze(x,y + 1,array,length + 1)
down = maze(x + 1,y,array,length + 1)
left = maze(x,y - 1,array,length + 1)
return min(up,down,left,right)
array = [[0,1,0,0,0],[0,0,0,1,0],[0,0,0,1,0]]
minLength = maze(0,0,array,1)
print(minLength)
I designed it so that it recursively finds all possible paths from each direction (up, down, left and right), and returns the lowest value from all these paths with each step of the way. It returns inf for any path that is not valid.
For this specific array, it returns 11, which is false, it should be 9. I do not believe it is merely a mathematical error, as I tried printing each step of the way and it is not recognizing certain paths (it returns inf for paths that most definitely have options).
I can't seem to find where my code is going wrong, it seems like it should properly return the value, but in practice it does not.
array is a reference to the original array, not a local copy. See any of the on-line tutorials on how Python passes function arguments, or how it handles lists. You can see the effect by printing array in your main program after the call to maze:
Final Maze [
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 0]
]
Fixing this is relatively easy: copy the nested list and use that copy locally.
from copy import deepcopy
def maze(x,y,array,length):
m = len(array)
n = len(array[0])
if x < 0 or y < 0 or x == m or y == n or array[x][y] == 1:
return float("inf")
elif x == m - 1 and y == n - 1:
return length
else:
new_maze = deepcopy(array)
new_maze[x][y] = 1
up = maze(x - 1,y,new_maze,length + 1)
right = maze(x,y + 1,new_maze,length + 1)
down = maze(x + 1,y,new_maze,length + 1)
left = maze(x,y - 1,new_maze,length + 1)
return min(up,down,left,right)
array = [[0,1,0,0,0],[0,0,0,1,0],[0,0,0,1,0]]
minLength = maze(0,0,array,1)
print("Final Maze", array)
print(minLength)
The output from this is (edited for readability again)
Final Maze [
[0, 1, 0, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 1, 0]
]
9

How to combine the result of nested loop in Python

I need help to do the combination of nested loop output from two iteration.
This is my nested while code:
iteration=0
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
And this is the result:
List of bit: [1, 0, 1, 1, 0]
End of iteration 1
List of bit: [1, 0, 0, 1, 1]
End of iteration 2
However, I would like to combine the result of the loop. Supposedly, the result may produce something like this:
Combination of bit:[1, 0, 1, 1, 0 ,1 , 0, 0, 1, 1]
Hopefully someone may help me to do this.
Thank you so much.
This code should definitely be reorganized, but here is the solution.
from itertools import chain
# list for appending results
combined = []
iteration=0
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
# append the result
combined.append(numbers)
# print the combined list
print(list(chain.from_iterable(combined)))
Output
[1, 0, 1, 1, 0 ,1 , 0, 0, 1, 1]
Simply initialize numbers outside the loop, instead of clearing it for every iteration, so that your results can keep appending to numbers.
iteration=0
numbers = []
while (iteration < 2):
count = 0
bit=5
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
Given that the code simply creates a list of 10 random binary values, the code seems extremely complex. You could get the same effect with the following:
>>> import random
>>> [random.choice([0,1]) for _ in range(10)]
[0, 0, 0, 0, 1, 0, 1, 0, 1, 1]
However, as the code stands the list of values produced each iteration is thrown away at the start of the next iteration by the line numbers = [].
Either move this before the initial while statement, or create a separate list outside the while statement and append each iteration to it.
This latter approach (with minimal changes to your code) would look like this:
iteration=0
all_numbers = [] # List to hold complete set of results
while (iteration < 2):
count = 0
bit=5
numbers = []
while (count < bit):
Zero = 0
One = 1
IV=(random.choice([Zero, One]))
numbers.append(IV)
count= count + 1
print ('List of bit:', numbers)
iteration=iteration + 1
print ("End of iteration",iteration)
all_numbers.extend(numbers) # Add the iteration to the complete list
print ('Complete list', all_numbers) # Show the aggregate result
your numbers variable is being re-initialized in the outer loop.
Other answers already pointed where your error was, but really that's WAY too much code for such a simple thing. The pythonic way is a much simpler and more readable one-liner:
numbers = [random.randint(0,1) for i in range(10)]

Categories