This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 5 years ago.
I'm trying to get an if statement to trigger from more than one condition without rewriting the statement multiple times with different triggers. e.g.:
if user_input == "look":
print description
if user_input == "look around":
print description
How would you condense those into one statement?
I've tried using 'or' and it caused any raw_input at all to trigger the statement regardless of whether the input matched either of the conditions.
if user_input == "look" or "look around":
print description
What you're trying to do is
if user_input == "look" or user_input == "look around":
print description
Another option if you have a lot of possibilities:
if user_input in ("look", "look around"):
print description
Since you're using 2.7, you could also write it like this (which works in 2.7 or 3+, but not in 2.6 or below):
if user_input in {"look", "look around"}:
print description
which makes a set of your elements, which is very slightly faster to search over (though that only matters if the number of elements you're checking is much larger than 2).
The reason your first attempt always went through is this. Most things in Python evaluate to True (other than False, None, or empty strings, lists, dicts, ...). or takes two things and evaluates them as booleans. So user_input == "look" or "look around" is treated like (user_input == "look") or "look_around"; if the first one is false, it's like you wrote if "look_around":, which will always go through.
You could use regular expressions to match the strings if they follow a pattern with
optional sections or you could do an array lookup:
if user_input in ["look", "look around"]:
print description
The boolean operator or only works with boolean values, it evaluates the expressions
on both sides and returns True if one of the expressions evaluates to True.
It has nothing to do with the natural language '
Related
This question already has answers here:
Skip elements on a condition based in a list comprehension in python
(3 answers)
Closed last month.
I want to check if an item is in a list and if not, I want to append it to the list.
Usually I would write it:
if item not in list:
list.append(item)
else:
pass
However, I got to the point where I try to keep my code shorter and got to this:
list.append(item) if item not in list else list
To be fair, only list.append(item) if item not in list is my own creation. The else statement is due to insistence of PyCharm.
Now to my question: Why can't I follow up the else statement with pass but must write list instead. I can't wrap my head around it, nor did Google help too.
Thanks for your clarifications.
There is a difference between an if statement and a conditional expression.
When you write
if condition:
this()
else:
that()
you are writing a statement. It is an imperative construct — it does something. And the else bit is optional; if it is omitted, the statement will do nothing if the condition is not fulfilled.
The this if condition else that construct is an expression. It computes a value. It always has to compute a value, so the else bit has to be there. Using it for its side effects, for example by calling `list.append(), which doesn't return anything useful, is... not exactly wrong, but... well, it is wrong. Not technically, but philosophically.
So, when you want to compute a value, in one of two possible ways, and the whole thing fits in a line or so, use a conditional expression. If you want to do either of two things, one of which may be nothing, use an if statement.
Notice that you write
if temperature < 0:
coat = thick
else:
coat = thin
but
coat = thick if temperature < 0 else thin
In the first case, you have an if statement that selects which of two assignment statements to execute. In the second case, you have a single assignment statement, which uses a conditional expression to decide which value to assign.
Expressions can be used as statements (in which case their value is simply ignored), but statements have no value, and thus cannot be used as expressions.
In your first snippet, the else statement is redundant, i.e.
if item not in a_list:
list.append(item)
is enough and is as short and idiomatic as it can get (you might want to try sets for performance though).
In the second snippet, you're using a conditional expression to append to a list, which is not what those expressions are for. A conditional expression must have a value regardless of the condition, and pass is not a value. Use the conditional statements like above unless you need to compute a value based on the condition.
From docs(also provided by Pycharm):
pass is a null operation — when it is executed, nothing happens. It is useful as a placeholder when a statement is required syntactically, but no code needs to be executed, for example:
def f(arg): pass # a function that does nothing (yet)
In python it's not allowed if you are using ternary operator interpretation, so in else you need to do something
so your solution is:
if item not in list:
list.append(item)
Or use set()
set.add(item)
You can shorten your code even more by using the and operator
item not in list and list.append(item)
It will only execute list.append(item) if item not in list returns True
This question already has answers here:
Why does comparing strings using either '==' or 'is' sometimes produce a different result?
(15 answers)
Closed 9 years ago.
I noticed a Python script I was writing was acting squirrelly, and traced it to an infinite loop, where the loop condition was while line is not ''. Running through it in the debugger, it turned out that line was in fact ''. When I changed it to !='' rather than is not '', it worked fine.
Also, is it generally considered better to just use '==' by default, even when comparing int or Boolean values? I've always liked to use 'is' because I find it more aesthetically pleasing and pythonic (which is how I fell into this trap...), but I wonder if it's intended to just be reserved for when you care about finding two objects with the same id.
For all built-in Python objects (like
strings, lists, dicts, functions,
etc.), if x is y, then x==y is also
True.
Not always. NaN is a counterexample. But usually, identity (is) implies equality (==). The converse is not true: Two distinct objects can have the same value.
Also, is it generally considered better to just use '==' by default, even
when comparing int or Boolean values?
You use == when comparing values and is when comparing identities.
When comparing ints (or immutable types in general), you pretty much always want the former. There's an optimization that allows small integers to be compared with is, but don't rely on it.
For boolean values, you shouldn't be doing comparisons at all. Instead of:
if x == True:
# do something
write:
if x:
# do something
For comparing against None, is None is preferred over == None.
I've always liked to use 'is' because
I find it more aesthetically pleasing
and pythonic (which is how I fell into
this trap...), but I wonder if it's
intended to just be reserved for when
you care about finding two objects
with the same id.
Yes, that's exactly what it's for.
I would like to show a little example on how is and == are involved in immutable types. Try that:
a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True
is compares two objects in memory, == compares their values. For example, you can see that small integers are cached by Python:
c = 1
b = 1
>>> b is c
True
You should use == when comparing values and is when comparing identities. (Also, from an English point of view, "equals" is different from "is".)
The logic is not flawed. The statement
if x is y then x==y is also True
should never be read to mean
if x==y then x is y
It is a logical error on the part of the reader to assume that the converse of a logic statement is true. See http://en.wikipedia.org/wiki/Converse_(logic)
See This question
Your logic in reading
For all built-in Python objects (like
strings, lists, dicts, functions,
etc.), if x is y, then x==y is also
True.
is slightly flawed.
If is applies then == will be True, but it does NOT apply in reverse. == may yield True while is yields False.
This question already has an answer here:
Check if string in the exact form of "<int1>,<int2>" in Python
(1 answer)
Closed 6 years ago.
I'm converting a string of two integers into a tuple. I need to make sure my string is formatted exactly in the form of:
"<int1>,<int2>"
This is not a duplicate to an earlier question. Since that did not address restrictions I did not know about earlier. My parameter will be "4,5" for example. I'm not allowed to write other helper functions to check if they are formatted correctly. The checks must be done in a single function called convert_to_tuple
I just looked at the project specs again, and I'm not allowed to import any new modules, so regex is off the table. I'm also not allowed to use try/catch either.
Can you point me in the write direction? Thanks
Here is my code for converting the string into a tuple. So I need some type of check for executing this code.
if foo:
s1 = "12,24"
string_li = s1.split(',')
num_li = [int(x) for x in string_li]
num_tuple = tuple(num_li)
return num_tuple
else:
empty_tuple = ()
return empty_tuple
Does this work? (Edited to meet OP's requirements)
def is_int(string):
return string and set(string).issubset(set('1234567890'))
def check_str(s):
parts = s.split(',', 1)
return len(parts) == 2 and is_int(parts[0]) and is_int(parts[1])
I believe for testing (without converting, and without regexes or exception handling) a simple:
vals = s1.split(',')
if len(vals) == 2 and all(map(str.isdigit, vals)):
would verify that there are two components and both of them are non-empty and composed solely of digits.
This question already has answers here:
python-re: How do I match an alpha character
(3 answers)
Closed 4 years ago.
Ok so basically this is what I know, and it does work, using Python3:
color="Red1 and Blue2!"
color[2]=="d"
True
What I need is that when I call any position, (which inputs any single character Lower or Upper case in the comparison), into the brackets "color[ ]" and compare it to match only with "Lower or Upper case letters" excluding all numbers and characters (.*&^%$##!).
in order words something to the effects below:
color="Red1 and Blue2!"
if color[5]==[a-zA-z]:
doSomething
else:
doSomethingElse
Of course what I just listed above does not work. Perhaps my syntax is wrong, perhaps it just cant be done. If I only use a single letter on the "right" side of the equals, then all is well, But like I said I need whatever single letter is pulled into the left side, to match something on the right.
First off I wan't to make sure that its possible to do, what I'm trying to accomplish?
2nd, if it is indeed possible to do then have this accomplished "Without" importing anything other then "sys".
If the only way to accomplish this is by importing something else, then I will take a look at that suggestion, however I prefer not to import anything if at all possible.
I'v searched my books, and a whole other questions on this site and I can't seem to find anything that matches, thanks.
For the case of looking for letters, a simple .isalpha() check:
if color[5].isalpha():
will work.
For the general case where a specific check function doesn't exist, you can use in checks:
if color[5] in '13579': # Checks for existence in some random letter set
If the "random letter set" is large enough, you may want to preconvert to a frozenset for checking (frozenset membership tests are roughly O(1), vs. O(n) for str, but str tests are optimized enough that you'd need quite a long str before the frozenset makes sense; possibly larger than the one in the example):
CHARSET = frozenset('13579adgjlqetuozcbm')
if color[5] in CHARSET:
Alternatively, you can use regular expressions to get the character classes you were trying to get:
import re
# Do this once up front to avoid recompiling, then use repeatedly
islet = re.compile('^[a-zA-Z]$').match
...
if islet(color[5]):
This is where isalpha() is helpful.
color="Red1 and Blue2!"
if color[5].isalpha():
doSomething
else:
doSomethingElse
There's also isnumeric(), if you need numbers.
Not really sure why you'd require not importing anything from the standard libraries though.
import string
color="Red1 and Blue2!"
if color[5] in string.ascii_letters:
print("do something")
else:
print("do something else")
This question already has answers here:
Does Python have a ternary conditional operator?
(31 answers)
Closed last month.
I've been working on a text-based game in Python, and I've come across an instance where I want to format a string differently based on a set of conditions.
Specifically, I want to display text describing items in a room. I want this to be displayed, in the room's description, if and only if the item object in question is in the room object's list of items. The way it is set up, I feel that simply concatenating strings based on conditionals will not output as I want, and it would be better to have a different string for each case.
My question is, is there any pythonic method for formatting strings based on the result of a Boolean conditional? I could use a for loop structure, but I was wondering if there was something easier, similar to a generator expression.
I'm looking for something similar to this, in string form
num = [x for x in xrange(1,100) if x % 10 == 0]
As a general example of what I mean:
print "At least, that's what %s told me." %("he" if gender == "male", else: "she")
I realize that this example is not valid Python, but it shows, in general, what I'm looking for. I'm wondering if there is any valid expression for boolean string formatting, similar to the above.
After searching around a bit, I was unable to find anything pertaining specifically to conditional string formatting. I did find several posts on format strings in general, but that is not what I'm looking for.
If something like that does indeed exist, it would be very useful. I'm also open to any alternate methods that may be suggested.
Your code actually is valid Python if you remove two characters, the comma and the colon.
>>> gender= "male"
>>> print "At least, that's what %s told me." %("he" if gender == "male" else "she")
At least, that's what he told me.
More modern style uses .format, though:
>>> s = "At least, that's what {pronoun} told me.".format(pronoun="he" if gender == "male" else "she")
>>> s
"At least, that's what he told me."
where the argument to format can be a dict you build in whatever complexity you like.
Use an f-string:
plural = ''
if num_doors != 1:
plural = 's'
print(f'Shut the door{plural}.')
Or in one line with a conditional expression (a one-line version of the if/else statement):
print(f'Shut the door{"s" if num_doors != 1 else ""}.')
Note that in this case you have to mix double " and single ' quotes because you can't use backslashes to escape quotes in the expression part of an f-string, but this might change in Python 3.12. You can still use backslashes in the outer part of an f-string, so f'{2+2}\n' is fine.
There is a conditional expression in Python which takes the form:
A if condition else B
Your example can easily be turned into valid Python by omitting just two characters:
print ("At least, that's what %s told me." %
("he" if gender == "male" else "she"))
An alternative I'd often prefer is to use a dictionary:
pronouns = {"female": "she", "male": "he"}
print "At least, that's what %s told me." % pronouns[gender]