How could I do litteraly 1000 'or' conditions im my while, for image processing.
The goal here is to do this :
while (img0[i,j] != NOIR0).all() or (img0[i,j] != NOIR1) or (img0[i,j] != NOIR2) ... :
and this goes on to NOIR999, with NOIRx being different constants.
I thought to code a for that fulfil a string, but I can't put it as a condition in the while.
Could someone help me please ? :)
for the n you can do this:
while n<=999:
print(n)
n = n+1
This is the most basic layout of a while loop.
A while loop continues on forever until a condition is met.
If you want a for loop:
for n in range(0, 1000):
print(n)
What you are looking for is the built-in any() function.
This function receives an iterator and will return True if any of the items is evaluated to True, else it will return False.
The good thing with that is short-circuiting - whenever a True value is encountered, the function will not continue with the iterable.
while any((img0[i, j] != f"NOIR{n}").all() for n in range(1000)):
Related
Almost every time I solve an exercise of Codewars and glance at others solutions I see that some guys do my 15 lines code in 2 or 3 lines. So, I have started to learn lists and sets comprehensions and would try other tricks. For now my question is about this code:
for i in range (0, 3):
if not text [i].isdecimal ():
return False
Is it possible to write it in one line?
Use all:
return all(text[i].isdecimal() for i in range(0,3))
all iterates through your list/generator/tuple/etc. and evaluates whether each item is true or false. It bails and returns False the first time it evaluates a False. any is similar, except it will look through everything for at least one truthy evaluation.
(I am assuming your original code is correct, and you're only interested in the first three elements of text, and that you're looking to return that value from whatever function you're in.)
You have a more complex loop like this:
for i in range(10):
if i<5:
j = i**2
else:
j = 0
print(j) ```
You can compress this into one line. Check out the following code snippet:
for i in range(10): print(i**2 if i<5 else 0)
I recently had an idea of doing sigma(Σ) using python
So, I wrote this code.
def sigma(i,target,condition='i'):
if condition=='i':
a=0
for f in range(i,target+1): #the loop sums all the numbers from i to the target given
a+=f
print(a)
'''if user enters a condition than,
every number will follow condition and then be added to each other'''
else:
lis=list()
condition for i in range(i,target+1):
lis.append(i)
print(sum(lis))
but the code I wrote above just gives me a wrong output as it takes the variable condition as type 'string'.
The problem is actully to take the argument condition not as a string
for example, let's say user entered:
sigma(1,100,condition='i'*2)
so the code should run for loop like this:
i*2 for i in range(i, target+1)
but it runs like this:
'ii' for i in range(i, target+1)
For what I can understand, you should pass an anonymous function as argument to accomplish what you are looking for.
Consider that this is not a valid syntax: i*2 for i in range(i, target+1), so I consider it as a pseudo code explained by your comment.
You should change your method in this way:
def sigma(i, target, condition='i'):
if condition=='i':
a=0
for f in range(i,target+1):
a+=f
print(a)
else:
lis=list()
for i in range(i, target+1):
lis.append(i)
print(condition(sum(lis)))
So that if you call sigma(1,100,'i') #=> 5050 you fall in the true part of the statement.
For the false part of the statement you need to call the method passing a lambda expression as parameter:
sigma(1,100, lambda i: 2*i) #=> 10100
It happens that the argument condition when passed as lambda works as if it was defined as:
def condition(i):
return 2 * i
I would like to point out that the sum of the first n natural numbers is given by a math formula, so you don't need a loop:
n * (n + 1) // 2
Also should be better to return a value than to print.
I'd rewrite the method:
def sigma_2(i, target, condition=None):
sum_i_to_target = (target*(target+1)-(i-1)*i)//2
if condition is not None:
return condition(sum_i_to_target)
else: # need to check that condition is a lambda function
return sum_i_to_target
So call this way:
sigma_2(2, 20) #=> 209
sigma_2(2, 20, lambda i: 2*i) #=> 418
You've initialized i from what I can see from your code as a string.
If you would like for the compiler to read it as int then initialize i as int.
For example:
i=1
I have a list of random numbers. I want to refine the list so that there is no pair of numbers that has a product of 0.5. I am trying to use the next method for python generator so that I can continue the loop as soon as the condition is met. Another reason is that I want to avoid a nested for-loop, so that the code can continue the main loop when the condition is met.
It's worth noting that in my real case the computational cost to check the condition is very expensive, and this is why I want to use a generator, so that I can continue the loop as soon as the condition is met, instead of checking the condition with all current existing numbers in refined_list. Here I just use a simple condition i * j == 0.5 as an example.
Below is my code
import random
rands = [random.uniform(0,1) for _ in range(100)]
refined_list = []
for i in rands:
if refined_list: # Make sure the refined list is not empty
if next(j for j in refined_list if i * j == 0.5):
continue
refined_list.append(i)
print(refined_list)
However, I get the StopIteration error once the condition is met.
So how should I continue the loop using a generator? Or is there a better way to do this?
The problem is in next it self, either your condition is true, either is raises the exception
You may use any
for i in rands:
if refined_list: # Make sure the refined list is not empty
if any(j for j in refined_list if i * j == 0.5):
continue
refined_list.append(i)
You could refactor the condition to group the condition, and get
for i in rands:
if not (refined_list and any(j for j in refined_list if i * j == 0.5)):
refined_list.append(i)
This is working fine but I just don't get it why this works in this way. I think the return of True value should be inside the for loop but when I run this program it works in the opposite way.
Can someone point out what i am misunderstanding about the indentation of return values?
Even though the solution was even shorter I wanted to know exactly about my way of coding. Please help!
# My attempt
def palindrome(s):
mylist = list(s)
j = -1
for i in range(0,len(mylist)-1):
if mylist[i] == mylist[j]:
i+=1
j-=1
continue
return False
return True
# Solution answer:
def palindrome(s):
return s == s[::-1]
When a function is called, the function can return only once.
This kind of return pattern is very frequently found across various programming languages. It is intuitive and efficient.
Let's say you have to check if a list of 1000 values contain only even numbers. You loop through the list and check if each element is even. Once you find an odd number, you do not need to go further. So you efficiently and immediately return and exit from the loop.
Here is hopefully a little bit more intuitive version of your code:
def palindrome(s):
l, r = -1, 0 # left, right
for _ in range(0, len(s) // 2 + 1): # more efficient
l += 1
r -= 1
if s[l] != s[r]:
return False
return True
Once you know the input is not palindrome, you do not need to go further.
If you did not need to stop, it is palindrome.
They follow the exact same rules as any other statement. What you have written means
def palindrome(s) {
mylist = list(s)
j = -1
for i in range(0,len(mylist)-1) {
if mylist[i] == mylist[j] {
i+=1
j-=1
continue
}
return False
}
return True
}
# My attempt
def palindrome(s):
mylist = list(s)
j = -1
for i in range(0,len(mylist)-1):
if mylist[i] == mylist[j]:
i+=1
j-=1
continue
return False
return True
In the above code what happens is inside the for loop each time it checks if there is a mismatch in the values by comparing values by iterating over the list forwards using variable "i" and backwards using variable "j". and returns false immediately if any one letter mismatches and so exits from the loop. And true is returned only once the for loop is completed which means no mismatch was found in the loop
Note: i=0 gives first index, i+=1 iterates forward and j=-1 gives last index, j-=1 iterates backward
Basically, when you index an array in numpy, you do it the way:
a[start:end:step]
,for every dimension. If step is negative, you return the values in inverse order. So, if step is -1, the array a[::-1] is the inverted array of a[::].
a[::-1] = a[::]
Then, if a sequence is the same as its inverse, by definition, it is a palindrome.
See:
https://www.geeksforgeeks.org/numpy-indexing/
There is an exercise in 6.00x edX whose answer's suggestion provided by them is as follows:
def genPrimes():
primes = [] # primes generated so far
last = 1 # last number tried
while True:
last += 1
for p in primes:
if last % p == 0:
break
else:
primes.append(last)
yield last
Looking to the identation I can clearly see that this ELSE is not related to the IF. I thought it was a bug but when I executed, the code was fine and I can't understand what is happening, what does that ELSE does?
It is executed when the for loop is done going through the list. But, in the case of the example you have. If the break is called the else will not be executed.
else part of your for loop executes, when your for loop runs successfully without breaking in the middle of the iteration.
So, in your example, : -
if last % p == 0:
break
if your above if condition in for loop becomes true in some iteration, it will break out of your for loop, and in that case your else will not execute.