Simplifying multiple "or" conditions in if statement. - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Simplifying multiple "or" conditions in if statement. (/thread-4073.html) |
Simplifying multiple "or" conditions in if statement. - rhubarbpieguy - Jul-20-2017 The first if statement, with "in s" after each string works. However, the second if statement, combining the strings with parentheses does not. It seems I shouldn't have to repeat "in s." Is there a way? s='Bob' 'Tom' if 'Tom' in s or 'Bob' in s: if ('Tom' or 'Bob') in s: RE: Simplifying multiple "or" conditions in if statement. - micseydel - Jul-20-2017 https://python-forum.io/Thread-Multiple-expressions-with-or-keyword :) RE: Simplifying multiple "or" conditions in if statement. - Larz60+ - Jul-21-2017 works for me python 3.6.2 >>> s='Bob' 'Tom' >>> s 'BobTom' >>> ('Tom' or 'Bob') 'Tom' >>> 'Tom' in s True >>> 'Bob' in s True >>> if ('Tom' or 'Bob') in s: ... print('Yup') ... Yup >>> RE: Simplifying multiple "or" conditions in if statement. - AussieSusan - Jul-21-2017 Be a little careful of the way you test an expression such as this. What could be happening is that it is just taking one of the values and using that. You probably should test if 'Bob' or 'Carol', 'Alice' or 'Bob', 'Ted' or 'Alice' and even 'Carol' or 'Bob' (i.e. is it just taking the first name) also produce the required result. (The principle behind this is to test edge cases, and for false positives and false negatives.) Susan RE: Simplifying multiple "or" conditions in if statement. - rhubarbpieguy - Jul-21-2017 Quote:works for me I'm sorry, I mistyped my example. I meant to search on something not in the string; in the corrected example Ed. The first works but the second doesn't. However, I was confused as "if ('Bob' or 'Ed') in s:" works. Regardless, the link provided as a response helps. s='Bob' 'Tom' if 'Ed' in s or 'Bob' in s: if ('Ed' or 'Bob') in s: RE: Simplifying multiple "or" conditions in if statement. - DeaD_EyE - Jul-21-2017 if ('Ed' or 'Bob') in s:This code checks always if 'Ed' in s: The or operator is a binary operation, which is checking for trueness. A str object with the length 0 is False. All other str objects are True. With your code you'll always get 'Ed' after evaluating the expression. What you want to do: s = 'BobTom' for name in ('Bob', 'Ed'): if name in s: print('Name {} is in {}'.format(name, s))If you want to check if any of the names is in the string, you can write it more compact: any(name in s for name in ('Bob', 'Ed'))If you want to check if all the names are in the string, you can use the built-in function all: all(name in s for name in ('Bob', 'Ed')) RE: Simplifying multiple "or" conditions in if statement. - rhubarbpieguy - Jul-21-2017 (Jul-21-2017, 01:32 PM)DeaD_EyE Wrote: If you want to check if any of the names is in the string, you can write it more compact: Wonderful. I knew I could use a loop but was looking for something more compact. However, I don't see the need for "any." The following seems to work: (name in s for name in ('Bob', 'Ed'))Is there an advantage to using "any" I'm not seeing. I understand using "all" if that's required. RE: Simplifying multiple "or" conditions in if statement. - DeaD_EyE - Jul-22-2017 The last call is every time true, because it's a generator expression. g = (name in s for name in ('Bob', 'Ed')) print(g) # Nothing is evaluated, it evaluates lazy print(next(g)) print(next(g)) print(next(g)) # this will raise a StopIterationPython supports following shortcuts:
Now we come to the point that, all() and any() , takes iterables and valuates to bool(element) all([True, True, True]) == True all([True, False, True]) == False # all elements have to be checked any([False, False, True]) == True # iterates till end has been reached any([False, True, False]) == True # stops after second iteration You can also pass a generator expression functions, if they are the only argument. In this case you don't have to use the parenthesis twice. any((e for e in [False])) # this is valid any(e for e in [False]) # this is validIf you have a function, which takes more than one argument, you have to use parenthesis for a generator expression: def foo(iterable, start): for index, element in enumerate(iterable, start): print(index, element) foo((word for word in ['Hello' ,'World']), 1) # this is valid foo((word for word in ['Hello' ,'World']), 1) # SyntaxError: Generator expression must be parenthesized if not sole argumentInstall ipython for Python3, which gives you better tabulator completion. Then play around inside the repl. In [1]: s = 'BobTom' In [2]: any(name in s for name in ('Bob', 'Ed')) Out[2]: True In [3]: all(name in s for name in ('Bob', 'Ed')) Out[3]: False In [4]: (name in s for name in ('Bob', 'Ed')) Out[4]: <generator object <genexpr> at 0x7f916f882c50> In [5]: bool(name in s for name in ('Bob', 'Ed')) Out[5]: True In [6]: bool([]) Out[6]: False In [8]: bool(tuple()) Out[8]: False In [9]: bool('') Out[9]: False In [10]: bool('Foo') Out[10]: True In [11]: bool('False') Out[11]: True In [12]: bool('0') Out[12]: True In [13]: [name in s for name in ('Bob', 'Ed')] Out[13]: [True, False] In [14]: {name in s for name in ('Bob', 'Ed')} Out[14]: {False, True} In [15]: {name: name in s for name in ('Bob', 'Ed')} Out[15]: {'Bob': True, 'Ed': False} In [16]: (name in s for name in ('Bob', 'Ed'))I hope this explains the use of list/dict/set comprehensions and generator expressions a little bit. When you're using the if statement, it evaluates the bool. The object itself decides what it should return when __bool__() is called. When calling bool(the_object)
You want to avoid the use of the three last examples. I am not sure about any use case to check the truthiness of a function, generator, class... But you can do it accidentally, which gives you some output without an error, which leads to wrong conclusions. RE: Simplifying multiple "or" conditions in if statement. - rhubarbpieguy - Jul-22-2017 (Jul-22-2017, 09:09 AM)DeaD_EyE Wrote: The last call is every time true, because it's a generator expression. A good answer quite well explained. I thank you kindly. |