They are not the same; using difflib.ndiff() shows how these two values differ very clearly:
>>> import difflib
>>> print '\n'.join(difflib.ndiff([x1], [x2]))
- N C Soft - NCSOFT_Guild Wars 2 December 2013 :: BNLX_AD_Parallax_160x600
? ^^ ^
+ N C Soft - NCSOFT_Guild Wars 2 December 2013 :: BNLX_CT_Parallax_160X600
? ^^ ^
In general, when in doubt use repr() to look at the representation. Python 2 will use escapes for any non-printable or non-ASCII character in the string, any 'funny' characters will stand out like a sore thumb. In Python 3, use the ascii() function for the same result as repr() there is less conservative and Unicode is rife with character combinations that look the same at first glance.
For strings where you still cannot see what changes between the two, the above difflib tool can also help point out what exactly changed.
python - Why does comparing strings using either '==' or 'is' sometimes produce a different result? - Stack Overflow
Strings look equal but aren't
Python - two strings appear to be equal but are not - Stack Overflow
Python: Comparing two strings that should be the same but that are not - Stack Overflow
is is identity testing, and == is equality testing. What happens in your code would be emulated in the interpreter like this:
>>> a = 'pub'
>>> b = ''.join(['p', 'u', 'b'])
>>> a == b
True
>>> a is b
False
So, no wonder they're not the same, right?
In other words: a is b is the equivalent of id(a) == id(b)
Other answers here are correct: is is used for identity comparison, while == is used for equality comparison. Since what you care about is equality (the two strings should contain the same characters), in this case the is operator is simply wrong and you should be using == instead.
The reason is works interactively is that (most) string literals are interned by default. From Wikipedia:
Interned strings speed up string comparisons, which are sometimes a performance bottleneck in applications (such as compilers and dynamic programming language runtimes) that rely heavily on hash tables with string keys. Without interning, checking that two different strings are equal involves examining every character of both strings. This is slow for several reasons: it is inherently O(n) in the length of the strings; it typically requires reads from several regions of memory, which take time; and the reads fills up the processor cache, meaning there is less cache available for other needs. With interned strings, a simple object identity test suffices after the original intern operation; this is typically implemented as a pointer equality test, normally just a single machine instruction with no memory reference at all.
So, when you have two string literals (words that are literally typed into your program source code, surrounded by quotation marks) in your program that have the same value, the Python compiler will automatically intern the strings, making them both stored at the same memory location. (Note that this doesn't always happen, and the rules for when this happens are quite convoluted, so please don't rely on this behavior in production code!)
Since in your interactive session both strings are actually stored in the same memory location, they have the same identity, so the is operator works as expected. But if you construct a string by some other method (even if that string contains exactly the same characters), then the string may be equal, but it is not the same string -- that is, it has a different identity, because it is stored in a different place in memory.
I've got two strings: one is a line read from a textfile. One is the result of some concatenated strings. They look the same. When I print them, they print the same. But if I compare them, Python says they are different. Any ideas why?
An example string is "IMAGE=00012n091.png"
I avoided the problem by using "in" to look for n091, but I still want to know why a straight comparison didn't work.
It turns out that two of the characters in the key in question had "unusual" ASCII values. When I have a string 'c', python assumes I'm referring to the character with ASCII value of 99, whereas the 'c' character in the data structure created by mutagen used ASCII value 169.
I had simply to determine the ASCII values of the individual characters of the string with ord and use them to build the correct string for the key 'cnam' using chr.
>>> the_key == 'cnam'
False
>>> ord(the_key[0])
169
>>> ord(the_key[3])
109
>>> new_key = chr(169)+'na'+chr(109)
>>> new_key
'cnam'
>>> new_key == the_key
True
I did not have to check the ASCII values of the characters 'n' and 'a' because it was shown in the question that the "default" ASCII values for 'n' and 'a' already matched those of the string in question.
You should take a look into the mutagen api:
https://mutagen.readthedocs.io/en/latest/api/mp4.html
class mutagen.mp4.MP4Tags
Bases: mutagen._util.DictProxy, mutagen.TagsDictionary containing Apple iTunes metadata list key/values.
Keys are four byte identifiers, except for freeform (‘—-‘) keys. Values are usually unicode strings, but some atoms have a special structure:
Text values (multiple values per key are supported):
‘\xa9nam’ – track title
‘\xa9alb’ – album
‘\xa9ART’ – artist etc.
print ( '\xa9') #
©
It's likely that extra spacing is your culprit. You may also try downcasing the string.
SentenceIMLookingfor='blha blha blah'
with open('textfile.lua','r') as my_file:
for line in my_file:
if line.lower().strip() == SentenceIMLookingfor:
#DO_SOMETHING
If, however, you are not checking for a line that is exactly equal to the Sentence you're looking for, you'll want to use the in operator to check for equality, so replace the if above with
if SentenceIMLookingfor in line.lower(): # you may not want .lower()
Since there is no need to read the entire file into memory, you can iterate over the lines of the file with for line in my_file. .lower() converts a string to all lower-case letters, .strip() cuts off any preceding or trailing whitespace
As suggested by @SethMMorton in the comments, you can use enumerate to iterate with the line numbers for i, line in enumerate(my_file)
If you are trying to collect the line numbers that this string appears on (which seems likely) you can accomplish that with a list comprehension
with open('textfile.lua','r') as my_file:
line_nos = [i for i, line in enumerate(my_file) if line.lower().strip() == SentenceIMLookingfor]
The problem was indeed the spacing. To get it to work I slightly change my condition if to this:
if(raw_dadat[i].strip()==SentenceIMLookingfor.strip()):
And it worked! Thanks a lot to all of you!( Also for the extra advices).
Copy paste the ệ of the first "liệu" in the second "liệu" or vice versa. That should make sure both are the exact replicas of each other. That should definitely give you this output:
b'li\xe1\xbb\x87u'
b'li\xe1\xbb\x87u'
True
Hope this helps!
As you can see with the bytes representation they are both different strings:
>>> a = 'liệu'
>>> b = 'liệu'
>>> a == a
True
>>> b == b
True
>>> a == b
False
They differ after the third letter:
>>> for l1, l2 in zip(a, b):
... print(l1 == l2)
...
True
True
False
False
This doesn't mean that the u is different,but for sure the e is.
When you print 'L-Air1993\n' it will look like it has just the name. The newline just adds a newline at the end but it's hard to see if nothing comes after it.
To remove all the new lines from your list, try this:
sellers_no_newlines = [x.strip() for x in sellers]
And then compare the online sellers list to sellers_no_newlines. Hopefully that solves your problem.
You can use the method strip in the function get_mysellers to remove the '\n' from the string.
def get_mysellers():
s = open("sellers.txt" , 'r')
sellers = []
for line in s:
Line=line.strip('\n')
sellers.append(Line)