Given:
if parse_rec[i] != col_data:
parse_rec[i] = col_data
data_changed = True
print str(i)
print str(parse_rec[i])
print str(col_data)
print type(parse_rec[i])
print type(col_data)
print len(parse_rec[i])
print len(col_data)
print parse_rec[i] != col_data
I get:
10
1037864
1037864
<type 'str'>
<type 'str'>
7
7
False
If I change the test to:
if str(parse_rec[i]) != str(col_data):
It works as expected and the 'if' condition fails (they are equal) and nothing prints. What is the str() doing? Why do I need it? Can I not trust any string comparisons in Python?
I have verified it. There are no tabs in my file.
This would happen if e.g. parse_rec[i] originally contained the number 10 while col_data contained the string '10'. str converts any Python object to a string representation; converting both of them (with one already being a string) would make them equal.
Your two data are strings and can be safely compared with the == operator.
What str() does:
Return a string containing a nicely printable representation of an object. For strings, this returns the string itself.
If you had an integer and a string, str() becomes necessary:
print 123 == '123' # false
print 123 is '123' # false
print str(123) == '123' # true
print '123' == '123' # true
print '123' is '123' # false
Related
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.
This question already has answers here:
Why empty string is on every string? [duplicate]
(2 answers)
Closed 6 years ago.
As I am going through tutorials on Python 3, I came across the following:
>>> '' in 'spam'
True
My understanding is that '' equals no blank spaces.
When I try the following the shell terminal, I get the output shown below it:
>>> '' in ' spam '
True
Can someone please help explain what is happening?
'' is the empty string, same as "". The empty string is a substring of every other string.
When a and b are strings, the expression a in b checks that a is a substring of b. That is, the sequence of characters of a must exist in b; there must be an index i such that b[i:i+len(a)] == a. If a is empty, then any index i satisfies this condition.
This does not mean that when you iterate over b, you will get a. Unlike other sequences, while every element produced by for a in b satisfies a in b, a in b does not imply that a will be produced by iterating over b.
So '' in x and "" in x returns True for any string x:
>>> '' in 'spam'
True
>>> "" in 'spam'
True
>>> "" in ''
True
>>> '' in ""
True
>>> '' in ''
True
>>> '' in ' '
True
>>> "" in " "
True
The string literal '' represents the empty string. This is basically a string with a length of zero, which contains no characters.
The in operator is defined for sequences to return “True if an item of s is equal to x, else False” for an expression x in s. For general sequences, this means that one of the items in s (usually accessible using iteration) equals the tested element x. For strings however, the in operator has subsequence semantics. So x in s is true, when x is a substring of s.
Formally, this means that for a substring x with a length of n, there must be an index i which satisfies the following expression: s[i:i+n] == x.
This is easily understood with an example:
>>> s = 'foobar'
>>> x = 'foo'
>>> n = len(x) # 3
>>> i = 0
>>> s[i:i+n] == x
True
>>> x = 'obar'
>>> n = len(x) # 4
>>> i = 2
>>> s[i:i+n] == x
True
Algorithmically, what the in operator (or the underlying __contains__ method) needs to do is iterate the i to all possible values (0 <= i < len(s) - n) and check if the condition is true for any i.
Looking back at the empty string, it becomes clear why the '' in s check is true for every string s: n is zero, so we are checking s[i:i]; and that is the empty string itself for every valid index i:
>>> s[0:0]
''
>>> s[1:1]
''
>>> s[2:2]
''
It is even true for s being the empty string itself, because sequence slicing is defined to return an empty sequence when a range outside of the sequence is specified (that’s why you could do s[74565463:74565469] on short strings).
So that explains why the containment check with in always returns True when checking the empty string as a substring. But even if you think about it logically, you can see the reason: A substring is part of a string which you can find in another string. The empty string however can be find between every two characters. It’s like how you can add an infinite amount of zeros to a number, you can add an infinite amount of empty strings to a string without actually modifying that string.
As Rushy Panchal points out, in inclusion operator follows set-theoretic convention and assumes that an empty string is a substring of any string.
You can try to persuade yourself why this makes sense by considering the following: let s be a string such that '' in s == False. Then '' in s[len(s):] better be false by transitivity (or else there is a subset of s that contains '', but s does not contain '', etc). But then '' in '' == False, which isn't great either. So you cannot pick any string s such that '' not in s which does not create a problem.
Of course, when in doubt, simulate it:
s = input('Enter any string you dare:\n')
print('' in '')
print(s == s + '' == '' + s)
print('' in '' + s)
I'm having an issue with isinstance().
I'm using Python 2.7.8, and running scripts from the shell.
The array element I'm testing for contains a number, but this function returns false; using number.Numbers:
import numbers
...
print array[x][i]
>> 1
...
print isinstance(array[x][i], numbers.Number)
>>> False
Also tried this, from this post
import types
...
print isinstance(array[x][i], (types.IntType, types.LongType, types.FloatType, types.ComplexType))
>>> False
From the same post, I tried
isinstance(array[x][i], (int, float, long, complex))
I also tried this solution did not work.
All return false.
You don't have a number; you most probably have a string instead, containing the digit '1':
>>> value = '1'
>>> print value
1
>>> print 1
1
This is not a number; it is a string instead. Note that printing that string is indistinguishable from printing an integer.
Use repr() to print out Python representations instead, and / or use the type() function to produce the type object for a given value:
>>> print repr(value)
'1'
>>> print type(value)
<type 'str'>
Now it is clear that the value is a string, not an integer, even though it looks the same when printed.
For actual numeric values, isinstance() together with numbers.Number works as expected:
>>> from numbers import Number
>>> isinstance(value, Number)
False
>>> isinstance(1, Number)
True
varA = 1
varB = 2
Code w/ Correct Result:
if type(varA) == type('a') or type(varB) == type('a'):
print "string involved (either varA or varB is a string)"
else:
print "varA and varB are not strings"
Code w/ Incorrect Result:
if type(varA) or type(varB) == type('a'):
print "string involved (either varA or varB is a string)"
else:
print "varA and varB are not strings"
Why exactly does the 2nd set of code not return the expected result (i.e. "varA and varB are not strings")? What is the step-by-step breakdown of what Python is doing with the 2nd set of code? I found a similar question had already been answered but did not entirely understand the explanation. Python: If-else statements.
In the second code snippet, the condition of the if-statement is being interpreted by Python like this:
if (type(varA)) or (type(varB) == type('a')):
Moreover, it will always evaluate to True.
This is because, no matter what the value of varA is, type(varA) evaluates to True:
>>> varA = 'a'
>>> bool(type(varA))
True
>>> varA = False
>>> bool(type(varA))
True
>>>
In fact, since Python's logical operators short-circuit (stop evaluating as soon as possible), the type(varB) == type('a') part of the condition will never even be evaluated.
On a separate note, you should be using is to compare types:
if type(varA) is str or type(varB) is str:
or, you can use isinstance:
if isinstance(varA, str) or isinstance(varB, str):
Your second example does not work because it parses as
if (type(varA)) or (type(varB) == type('a')):
and type(varA) will always be a class type which is considered True, so the whole expression will be True
There are better ways to do this
if any(isinstance(v, str) for v in (varA, varB)):
any takes an iterable and evaluates to True if anything in the iterable is true.
isinstance checks to see if the first argument "is a" second argument. Placing the generator expression inside of any reads as "if any v in (varA, varB) is a string): ... "
>>> var = 1
>>> isinstance(var, str) # var is an int, not a str
False
>>> isinstance(var, int)
True
>>> isinstance('a', int)
False
>>> isinstance('a', str) # 'a' is a str
True
iCodez is absolutely correct, but if you really want to do something along the lines of "list all elements and check if one of them is a string":
if str in map(type, [varA, varB]):
print "string involved"
Because in the second case you are not comparing both variables. Any integer above 0 would return True so you are not comparing types here.
if type(varA):
will always be True, because varA is equal to 1. You never even get to the second part of the condition.
I get the following result:
>>> x = '-15'
>>> print x.isdigit()
False
When I expect it to be True. There seems to be no built in function that returns True for a string of negative number. What is the recommend to detect it?
The recommended way would be to try it:
try:
x = int(x)
except ValueError:
print "{} is not an integer".format(x)
If you also expect decimal numbers, use float() instead of int().
There might be a more elegant Python way, but a general method is to check if the first character is '-', and if so, call isdigit on the 2nd character onward.
Maybe regex is an overhead here, but this could catch + and - before a number, and also could catch float and int as well:
(based on #Mark's comment)
CODE:
import re
def isdigit(string):
return bool(re.match(r'[-+]?(?:\d+(?:\.\d*)?|\.\d+)', string))
DEMO:
print isdigit('12') # True
print isdigit('-12') # True
print isdigit('aa') # False
print isdigit('1a2a') # False
print isdigit('-12-12') # False
print isdigit('-12.001') # True
print isdigit('+12.001') # True
print isdigit('.001') # True
print isdigit('+.001') # True
print isdigit('-.001') # True
print isdigit('-.') # False
Use lstrip:
>>> negative_number = "-1"
>>> negative_number.lstrip('-').isnumeric()
True
>>> positive_number = "2"
>>> positive_number.lstrip('-').isnumeric()
True