Meaning of in ""? Membership testing empty string literal - python

I stumbled upon this apparently horrific piece of code:
def determine_db_name():
if wallet_name in "":
return "wallet.dat"
else:
return wallet_name
What is supposed if xx in "": to mean? Doesn't it always evaluates to False?

It'll return True if wallet_name is itself empty:
>>> foo = ''
>>> foo in ''
True
It is horrific though. Just use if not wallet_name: instead, or use or and do away with the if statement altogether:
def determine_db_name():
return wallet_name or "wallet.dat"
which works because or short-circuits, returning wallet_name if it is not the empty string, otherwise "wallet.dat" is returned.

That expression is true if wallet_name is the empty string.
It would probably be clearer if the code had been written as follows:
if wallet_name == '':
Or just:
if not wallet_name:

Usually in is used when checking if a key exists in an array or an element exists in a list.
>>> 2 in [1,2,3]
True
>>> 6 in [1,2,3]
False
>>> 'foo' in {'bar', 'foo', 'baz'}
True
But it works for strings as well:
>>> 'foo' in 'barfoobar'
True
>>> 'foo' in 'barbarbar'
False

Related

Comparing two strings in Python 2.7

I have two strings that I compare, but I am not getting the result I want. Here's how I do it, with Python 2.7:
str1 = '0000644'
str2 = '0000644'
if str1 == str2:
print 'true!'
else:
print 'false'
I have also tried with the is comparison:
if str1 is str2:
print 'true'
else:
print 'false'
Can someone explain why I am not printing true when I do this? I come from C#, and if you do it like this you should print the true value.
The code you posted is not valid Python.
This will do:
str1 = '0000644'
str2 = '0000644'
if str1 == str2:
print True
else:
print False
To elaborate:
booleans start with capital letters: True and False (not sure why you had the exclamation)
blocks need to be consistently indented (unlike C# where you separate them with {})
else needs to finish with a colon
edit: my answer was based on OPs original code, which was not valid Python. I can't help if someone then changes the code into valid code after.
is will return True if two variables point to the same object, == if the objects referred to by the variables are equal.
>>> a = [17,27,37]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:] #shallow copy of a
>>> b is a
False
>>> b == a
True
In Python, 'true' and 'false' booleans need to be capitalized at the 'T' and 'F', respectively. Also, when printing, whatever you want to print needs to be surrounded in double or single quotes.

Differentiate False and 0

Let's say I have a list with different values, like this:
[1,2,3,'b', None, False, True, 7.0]
I want to iterate over it and check that every element is not in list of some forbidden values. For example, this list is [0,0.0].
When I check if False in [0,0.0] I get True. I understand that python casts False to 0 here - but how I can avoid it and make this check right - that False value is not in [0,0.0]?
To tell the difference between False and 0 you may use is to compare them. False is a singleton value and always refers to the same object. To compare all the items in a list to make sure they are not False, try:
all(x is not False for x in a_list)
BTW, Python doesn't cast anything here: Booleans are a subclass of integers, and False is literally equal to 0, no conversion required.
You would want to use is instead of == when comparing.
y = 0
print y == False # True
print y is False # False
x = False
print x == False # True
print x is False # True
Found a weird corner case on differentiating between 0 and False today. If the initial list contains the numpy version of False (numpy.bool_(False)), the is comparisons don't work, because numpy.bool_(False) is not False.
These arise all the time in comparisons that use numpy types. For example:
>>> type(numpy.array(50)<0)
<class 'numpy.bool_'>
The easiest way would be to compare using the numpy.bool_ type: (np.array(50)<0) is (np.False_). But doing that requires a numpy dependency. The solution I came up with was to do a string comparison (working as of numpy 1.18.1):
str(numpy.bool_(False)) == str(False)
So when dealing with a list, a la #kindall it would be:
all(str(x) != str(False) for x in a_list)
Note that this test also has a problem with the string 'False'. To avoid that, you could exclude against cases where the string representation was equivalent to itself (this also dodges a numpy string array). Here's some test outputs:
>>> foo = False
>>> str(foo) != foo and str(foo) == str(False)
True
>>> foo = numpy.bool_(False)
>>> str(foo) != foo and str(foo) == str(False)
True
>>> foo = 0
>>> str(foo) != foo and str(foo) == str(False)
False
>>> foo = 'False'
>>> str(foo) != foo and str(foo) == str(False)
False
>>> foo = numpy.array('False')
>>> str(foo) != foo and str(foo) == str(False)
array(False)
I am not really an expert programmer, so there may be some limitations I've still missed, or a big reason not to do this, but it allowed me to differentiate 0 and False without needing to resort to a numpy dependency.

Difference between: IF IN and IF == python

I wanted to know which condition is better to use for the following code:
Here are my two lists:
Matrix = ['kys_q1a1','kys_q1a2','kys_q1a3','kys_q1a4','kys_q1a5','kys_q1a6']
fixedlist = ['kys_q1a2', 'kys_q1a5']
Option 1:
for i, topmember in enumerate(Matrix):
for fixedcol in fixedlist:
if topmember in fixedcol:
print i
OR
Option 2:
for i, topmember in enumerate(Matrix):
for fixedcol in fixedlist:
if topmember == fixedcol:
print i
I understand that the comparison opertor is matching strings but isn't 'in' doing the same?
Thanks
topmember in fixedcol
tests if the string topmember is contained within fixedcol.
topmember == fixedcol
tests if the string topmember is equal to fixedcol.
So, 'a' in 'ab' would evaluate True. But 'a' == 'ab' would evaluate False.
I wanted to know which condition is better to use.
Since the two variants perform different operations, we cannot answer that. You need to choose the option that does the operation that you require.
Your code could be simplified quite a bit. The second option could be reduced to:
for i, topmember in enumerate(Matrix):
if topmember in fixedlist:
print i
You could also use a list comprehension to find the matching indices:
[i for i, x in enumerate(Matrix) if x in fixedlist]
If you just have to print the indices rather than store them in a list you can write it like this:
print '\n'.join([str(i) for i, x in enumerate(Matrix) if x in fixedlist])
It's a matter of taste whether you prefer the dense list comprehension one-liner, or the rather more verbose version above.
Hi in opeartor is used for membership testing and == operator is used for equality testing .
Generally we used in for membership testing in sequence object. And is able to test in dictionary, set, tuple, list, string etc. But it behaves differently based on the object types.
Dictionary:
It check for the key exists.
>>> d = {'key' : 'value'}
>>> 'key' in d
True
>>> 'k' in d
False
>>>
Set:
Under the hood it checks for key is exist, set implementation is same as dictionary with some dummy value.
>>> s = set(range(10))
>>> 1 in s
True
>>>
List and Tuple:
For the list and tuple types, x in y is true if and only if there exists an index i such that x == y[i] is true.
>>> l = range(10)
>>> 3 in l
True
>>>
String:
checking whether the substring is present inside the string eg. x in y is true if and only if x is a substring of y. An equivalent test is y.find(x) != -1
Use defined data type:
user-defined classes which define the __contains__() method, x in y is true if and only if y.__contains__(x) is true.
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __contains__(self, arg):
if arg in self.__dict__.keys():
return True
else:
return False
obj_p = Person('Jeff', 90)
print 'Jeff', 'Jeff' in obj_p
print 'age', 'age' in obj_p
print 'name', 'age' in obj_p
I Hope, you will clear some what is the usage of in.
Lets rewrite your snippet:
>>> Matrix = ['kys_q1a1','kys_q1a2','kys_q1a3','kys_q1a4','kys_q1a5','kys_q1a6']
>>> fixedlist = ['kys_q1a2', 'kys_q1a5']
>>> for i in fixedlist:
... print i, i in Matrix
...
kys_q1a2 True
kys_q1a5 True
>>>
And finally lets see some of the equality test: ==:
>>> 'a' == 'b'
False
>>> 'a' == 'a'
True
>>> 'a' == 'ab'
False
>>> '' in 'ab' # empty string is treated as a sub-string for any string
True
>>> '' == 'ab' # False as they are having different values
False
>>>
>>> 1 == 'ab'
False
>>> 1 == 1
True
>>>
Going with '==' is precise if you want to match exact string.

does adding element to a set return true if it is successful in python?

To my understanding, adding elements to a set does not return anything.
eg:
>>> s=set([1,2,3])
>>> s.add(1)
>>> b = s.add(1)
>>> b
>>> b = s.add(5)
>>> b
>>> print b
None
>>> b = s.add(5)
>>> print b
None
but I am confused how this function to remove duplicates of a list while preserving order works:
def f7(seq):
seen = set()
seen_add = seen.add
return [ x for x in seq if x not in seen and not seen_add(x)]
not seen_add(x) return true always irrespective of if I add duplicates or not.
The only real check is if x not in seen, since if that fails, it will not perform not see_add(x).
Is my understanding here or am I missing something?
however, here, not seen_add(1) return true if I add duplicate or a unique element.
This is puzzling, so is the not here just do an empty check? but seen_add() is not returning a set to do an empty check. and why seen_add(2) does not return anything but not seen_add(1) returns the boolean True
>>> seen=set()
>>> seen_add=seen.add
>>> seen_add(1)
>>> seen
set([1])
>>> seen.add(2)
>>> seen
set([1, 2])
>>> not seen_add(1)
True
>>> not seen_add(4)
True
As you have discovered, seen_add(x) always returns None.
Now, not None is True:
>>> not None
True
This is explained in the documentation:
5.1. Truth Value Testing
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:
None
False
...
Since not seen_add(x) is always True, it has no effect on the result of the if. It is only used for the side effect of adding x to seen.
Put another way, the following:
seen_add = seen.add
return [ x for x in seq if x not in seen and not seen_add(x)]
is a shorter (and likely more performant) way to write:
result = []
for x in seq:
if x not in seen:
result.append(x)
seen.add(x)
return result
As said by the others, not seen_add(x) always evaluates to True, so it is used only as a hack to add the addition statement into the list comprehension. Since the logic value of x and True is equal to x, this does not change the behavior of the if.
Another thing that this does, due to the short-circuit behavior of and, is that the right-hand argument to and is only executed if the left-hand argument is True. So the call to seen.add() is only done when the element is not yet in the set.
The equivalent python code would be:
def f7(seq):
seen = set()
result = []
for x in seq:
if x not in seen:
result.append(x)
seen.add(x)
return result
The solution with the list comprehension might be faster, but it is too cryptic to my taste.
This is because not None is True.
maybe this can help you
def add_ok(set, value):
return len(set) != (set.add(value), len(set))[1]
print(add_ok(a, 1))
print(add_ok(a, 1))

Why is a list containing objects False when value tested?

I would expect an empty list to value test as False, but I'm a bit confused why a reference for a list containing an object reports as False also when value tested as in the following example:
>>> weapon = []
>>> weapon == True
False
>>> weapon.append("sword")
>>> weapon == True
False
>>> weapon
['sword']
If weapon = [] is False, why would weapon = ['sword'] also be False? According to docs http://docs.python.org/release/2.4.4/lib/truth.html, it should be True. What am I missing in my understanding of this?
you should do a check like
In [1]: w = []
In [2]: if w:
...: print True
...: else:
...: print False
...:
False
When you do:
w = []
if w:
print "Truthy"
else:
print "Falsy"
the key thing to note is that whatever you are testing in the if clause is coerced to a boolean. To make it explicit:
w = []
if bool(w):
print "Truthy"
else:
print "Falsy"
To compare apples to apples then you don't want to compare ["sword"] to True. Instead you want to compare bool(["sword"]) to True:
bool(["sword"]) == True
# True
You need to use bool() if you want to compare it directly
>>> weapon = []
>>> bool(weapon) == True
False
>>> weapon.append("sword")
>>> bool(weapon) == True
True
When you test a condition using if or while, the conversion to bool is done implicitly
>>> if weapon == True: # weapon isn't equal to True
... print "True"
...
>>> if weapon:
... print "True"
...
True
From that article, note that even things are considered to have a "true" truth value, they are not necessarily == True. For example:
["hi"] == True
// False
if ["hi"]:
print("hello")
// prints hello
The documentation says "Any object can be tested for truth value" not that [] == False or ['whatever'] == True. You should test objects as specified in the documentation "for use in an if or while condition or as operand of the Boolean operation".

Categories