Several arguments in if statement - python

I have a script that relies on argparse. The mainbody of the script has if statements like this:
if results.short == True and results.verbose == False and results.verbose2 == False and results.list == False and results.true == False:
Isn't there any shorter way to do that? Say I have more than those 5 arguments, typing each of them in every statement seems like repetitive work.
Can't if do something like:
if results.short == True and "results.%s"== False % (everyotherresults.something):
I'm writing for Python 2.7

you shouldn't compare to bool in boolean expressions, eg:
if (results.short
and not results.verbose
and not results.verbose2
and not results.list
and not results.true):

You can use any function on list, and move all your arguments from 2nd in a list: -
if results.short and \
not any([results.verbose, results.verbose2, results.list, results.true]):
any function returns True if at least one value in the list is True. So, just use not any, which will return True if all the values in the list is False.
And yes, you don't need to compare boolean value with True or False.

Related

How to check elements of a list of variable length in an if statement python

I am new to python
I have a list of flags. and that list has a variable length. I want to check if all the variables in that list are true
I have tried
if (all in flags[x]==True):
finalFlags[x-1]=True
But that turned the final flag true when only one flag is true
finalFlags = False
if all(flags):
finalFlags=True
Edit: Simplified per comment from Chris:
finalFlags = all(flags)
Since you didn't post an example, i can suppose like this:
my_flags = [True, False, True, True, True, False]
valid_flags = 0
for flag in my_flags:
if flag == True:
valid_flags += 1
if len(my_flags) == valid_flags:
print("Total match")
else:
print("Matched ", valid_flags, " out of ", len(my_flags))
all and any functions can be used to check the boolean values inside the list.
test_list = []
all(iterable) returns True if all elements of the iterable are considered as true values (like reduce(operator.and_, iterable)).
any(iterable) returns True if at least one element of the iterable is a true value (again, using functional stuff, reduce(operator.or_, iterable)).
When you need to check all the values are true then you can use all() function as follow
all(test_list) #will return true
Also, you can use any() to check all values that are true but at this time, You need to convert the list elements from true to false and check whether if any true is there we can say there is a false in original list and we need to return false also when any() returns false which means there is no true value so in the original list we don't have true values
not all(not element for element in data)

I get an error when I end the if statement with a concluding else statement

I wrote this Python code that would check a list and return True if two items in the list next to each other are of the same value:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
Result 1:
>>> samer([1,3,44,5,5,8])
False
This is where I'm puzzled because I feel it should return True.
Result 2:
>>> samer([3,3,49,93,5,8])
True
It only returns True if the first and second number in the list is True.
The solution:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
return False
The above code works well, so my question is since the else statement indented under the if condition's purpose is to return False if no number in the list is next to each other in the process of the for loop, why do I still get False in Result 1?
Is it that it doesn't loop again after checking the first two boxes and why is that since it's the purpose of the for loop to go over each iteration and then check for the conditions?
When a function returns, that's it. The function is done, over, finished..
Since you're returning either true or false when checking each and every element, you really only check the first time through the loop (elements one and two), as you observe.
You should return true if a match is found and only return false at the end, when you've checked everything and, therefore, no matches are found. That code is already in your question, the bit under The solution.
So to chip in here, once that first iteration check occurs, we know that it's going to be returning False as the first two elements are not the same and the program ends there. If you want to really see that this is the case, make use of print() built-in function to see what's going on everytime the element is iterated within the for loop:
Like this:
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
print(True)
else:
print(False)
### adding a main method is always a good idea for clarity.
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is this:
False
False
False
True
False
See it returned True for the 3th element as they are equal and next to each other.
But with the way you had it structured in the first example it does return False as it hit the roadblock once it checked and saw that the first iteration were not equal to each other and thus returned False.
def samer(nums):
for i in range(0,len(nums)-1):
if (nums[i]) == (nums[i+1]):
return True
else:
return False
if __name__ == "__main__":
print(samer([1,3,44,5,5,8]))
Output is:
False
With your solution approach which is great, the loop only 'terminates' when it really cannot find a match (same two numbers), it will return False without depending on a else statement. So if it finds a match then it will return True which is does and then stops iterating and exits the program.

python if/else logic explained please

I have a really basic if/else logic question for Python. An exercise in the book required me to write a function that takes a list of integers are returns True if the list contains all even numbers and False if it doesn't.
I wrote:
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
else:
return True
This code always returns True. Why is that? Doesn't the code see the -1 during the loop of all the values of the list and returns the False?
list1 = [8,0,-2,4,-6,10]
list2 = [8,0,-1,4,-6,10]
def allEven(list):
for x in list:
if x % 2 != 0:
return False
return True
The book gives the answer of this. Why does this work and mine doesn't?
Pay close attention to where that else is placed. Indentation and nesting matters here!
In your first example, it will return True on the first element that satisfies your condition because your first if check fails.
In your second example, it will return True after all elements have been iterated through and a return value hasn't been produced.
The first function checks the first number only, since it returns something as soon as the for loop starts.
By the way, you can but should not use list as an argument or a variable name, since it is a keyword.
I strongly recommend writing a print statement to output x before both of your return statements. It will help you understand the flow of the code.
The short answer is that only the first element is being checked by your code, and the function returns True or False based on that value.
In the book solution, any failure causes a return of False, but the loop simply continues otherwise. Only if all elements are checked without failure does the return True reached.

Using "or" or "or-like" statements with Python 3.6

While tinkering around, I found out what my problem was with my last/current issue:
When using:
saveKey = gwdzd10q
saveKeyp = False
while [saveKeyp == True,str(saveKey(2)) == 'k']:
I get:
while [saveKeyp == True,str(saveKey(2)) == 'k']:
TypeError: 'str' object is not callable`
Why is this, and how can I fix it? Is it due to the way I am trying to do an or statement? Or what?
Do not mind the part, str(saveKey(2)) == 'k'] because I have one later on checking for several other keys, including "d"
I presume that by
saveKey = gwdzd10q
you mean
saveKey = "gwdzd10q"
If so, the third character of that string would be saveKey[2] rather than saveKey(2). This is a string already, so it is pointless to run it through str().
The condition that you seem to be trying to express is
saveKeyp or saveKey[2] == 'k'
Since saveKeyp is Boolean, using saveKeyp == True is superfluous.
If you want a while loop controlled by this it would be:
while saveKeyp or saveKey[2] == 'k':
but in that case the body of the loop would need to modify either saveKeyp or saveKey, otherwise you would have an infinite loop.
First, you need to use array syntax to get at the characters of saveKey:
while [saveKeyp == True,str(saveKey[2]) == 'k']:
Second, a non-empty list evaluates to boolean True. So you have set up an infinite loop here.
>>> bool([False, False])
True
>>> bool([False])
True
>>> bool([])
False
>>>

Boolean testing a list in Python

I was testing a list to see if it's empty or not. Normally I use len(list) == 0 and I vaguely remembered reading a little while ago that the correct way to test if a list is empty was whether it was True or false.
So I tried list is False, and that returned False. Maybe I'm suppose to be using == ?
Nope, that also returned false. list is True, returned false as did list == True.
Now I'm confused so I do a quick google and end up at: Best way to check if a list is empty
The top answer is:
if not a:
print "List is empty"
So I search around some more and end up in the python manual where 4.1 states:
Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below. The following values are considered false:
any empty sequence, for example, '', (), [].
Now I'm plain confused. If I test a list as if not list, it works fine. But if an empty list is false, then why can't I just do if list is False or if list == False?
Thanks
An empty list is not False, but when you convert it to a boolean, it converts to False. Likewise for dicts, tuples, strings, etc.:
>>> [] == False
False
>>> bool([]) == False
True
>>> {} == False
False
>>> bool({}) == False
True
When you put something in the condition of an if clause, it is its boolean value that is used for testing the if. That's why if someList is the same as if bool(someList). Likewise, not foo does a boolean not, so not [] equals True.
As other have said, in python bool([]) == False. One thing that is frequently exploited by python programmers is that the operators and and or don't (necessarily) return True/False. Consider the following:
3 and 4 #returns 4
0 and 8 #returns 0 -- This is short-circuit evaluation
0 or 8 #returns 8
True or 0 #returns True -- This is short-circuit evaluation
[] or False #returns False
False or [] #returns []
What happens in an if statement is that the condition gets evaluated as above and then python implicitly calls bool on the result -- So you can think of it as:
if condition:
is the same thing as:
if bool(condition):
as far as python is concerned. Similarly for the not operator:
not condition
is the same thing as
not bool(condition)
mylist is False means "is the object named mylist exactly the same object as False?"
mylist == False means "is the object named mylist equal to False?
not mylist means "does the object named mylist behave falsily?
None of these are equivalent: 1 is not 1.0 but 1 == 1.0 and [] != False but not [] is True.
Comparing the list to False, and testing the list's truth or falsehood aren't quite the same thing. An empty list isn't equal to False, but behaves as False in a boolean context.
Here's another way to say it that might help this make sense:
print (bool([]) == False) # will print True
print ([] == False) # will print False

Categories

Resources