3

I have this code to print some strings to a text file, but I need python to ignore every empty items, so it doesn't print empty lines.
I wrote this code, which is simple, but should do the trick:

lastReadCategories = open('c:/digitalLibrary/' + connectedUser + '/lastReadCategories.txt', 'w')
for category in lastReadCategoriesList:
    if category.split(",")[0] is not "" and category is not None:
        lastReadCategories.write(category + '\n')
        print(category)
    else: print("/" + category + "/")
lastReadCategories.close()

I can see no problem with it, yet, python keeps printing the empty items to the file. All categories are written in this notation: "category,timesRead", that's why I ask python to see if the first string before the comma is not empty. Then I see if the whole item is not empty (is not None). In theory I guess it should work, right?
P.S.: I've already tried asking the if to check if 'category' is not "" and is not " ", still, the same result.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
AugustoQ
  • 497
  • 1
  • 6
  • 16
  • 5
    `is not ""` is suspect. `is` checks for object identity, not object equality. Try `if ... != ""` – millimoose May 21 '13 at 21:46
  • 1
    You are looping over `lastReadCategoriesList`; what is it's definition? – Martijn Pieters May 21 '13 at 21:46
  • it is a list with items written like "category,timesRead", in which "timesRead" is an integer made into string. For some reason I still can't put my finger on, some empty items are being added to the list. – AugustoQ May 21 '13 at 21:49
  • @millimoose, It still adds the empty items, even using != "" and != " " – AugustoQ May 21 '13 at 21:53
  • can you give an example of your list? – PSS May 21 '13 at 21:55
  • @PSS: - right now, for example, my list is like this: ['A,52', 'B,1\n', 'C,50', ',3'], but I have no idea why it added that '\n' to the end of B,1 or that ',3', so I wanted not to print them. My code already doesn't print the ',3', but prints the line break, even if I add `category != '\n'` – AugustoQ May 21 '13 at 22:05
  • 1
    @millimoose is not "" will work in CPython, but that's a quirk of the interpreter and not a part of the language spec. Here's some more info: http://stackoverflow.com/questions/1392433/python-why-is-hello-is-hello – Joshmaker May 21 '13 at 22:06
  • @AugustQ You might either want to rstrip() your category to remove newline character, or somehow fix the issue whenever you create/populate the list to make sure newline character is not present. – PSS May 21 '13 at 22:16
  • @PSS What is the difference between strip() and rstrip() (if any) – AugustoQ May 21 '13 at 22:18
  • @AugustoQ: `.rstrip()` removes items from the right-hand side, `.strip()` from either side. There is a `.lstrip()` too, guess what it does? – Martijn Pieters May 21 '13 at 22:20
  • @PSS then why not just use `.strip()` – AugustoQ May 21 '13 at 22:22
  • @AugustoQ you can you .strip(), as Martijn pointed out .strip() removes leading and trailing characters, rstrip() only trailing. In your case you needed to remove latter that's why I offered .rstrip() – PSS May 21 '13 at 22:27

3 Answers3

4

Test for boolean truth instead, and reverse your test so that you are certain that .split() will work in the first place, None.split() would throw an exception:

if category is not None and category.split(",")[0]:

The empty string is 'false-y', there is no need to test it against anything.

You could even just test for:

if category and not category.startswith(','):

for the same end result.

From comments, it appears you have newlines cluttering up your data. Strip those away when testing:

for category in lastReadCategoriesList:
    category = category.rstrip('\n')
    if category and not category.startswith(','):
        lastReadCategories.write(category + '\n')
        print(category)
    else: print("/{}/".format(category))

Note that you can simply alter category inside the loop; this avoids having to call .rstrip() multiple times.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

rstrip() your category before writing it back to file

lastReadCategories = open('c:/digitalLibrary/' + connectedUser +'/lastReadCategories.txt', 'w')
for category in lastReadCategoriesList:
if category.split(",")[0] is not "" and category is not None:
    lastReadCategories.write(category.rstrip() + '\n')
    print(category.rstrip())
else: print("/" + category + "/")
lastReadCategories.close()

I was able to test it with your sample list provided (without writing it to file):

lastReadCategoriesList =  ['A,52', 'B,1\n', 'C,50', ',3']
for category in lastReadCategoriesList:
if category.split(",")[0] is not "" and category is not None:
    print(category.rstrip())
else: print("/" + category + "/")

>>> ================================ RESTART ================================
>>> 
A,52
B,1
C,50
/,3/
>>> 
PSS
  • 5,561
  • 5
  • 28
  • 30
  • It stoped printing the empty lines... Except for the one in "B,1\n". I mean, when I print it to the shell, it prints exactly like yours, but not on the file. Do you have any idea why that happens? (also, I added the rstrip() to the part of the code that generates the list and asked it to print the list when it was done generating it. It still printed "B,1\n") – AugustoQ May 21 '13 at 22:32
  • Can you give me the exact list? – PSS May 21 '13 at 22:32
  • @AugustoQ did you change this part lastReadCategories.write(category.rstrip() + '\n')? – PSS May 21 '13 at 22:33
  • @AugustoQ just tested with writing to file... works like a charm. – PSS May 21 '13 at 22:39
  • Yes, and that is why I'm finding it really strange, cause it makes no sense at all that it shoul print "B,1\n" (everything else is solved already) – AugustoQ May 21 '13 at 22:42
0

The classic way to test for an empty string (ie, only whitespace but not '') is with str.strip():

>>> st='   '
>>> bool(st)
True
>>> bool(st.strip())
False

Which also works on a null string:

>>> bool(''.strip())
False

You have if category.split(",")[0] is not "" ... and this is not the recommended way. You can do this:

if category.split(',')[0] and ...

Or, if you want to be wordier:

if bool(category.split(',')[0]) is not False and ...

And you may be dealing with an issue with leading whitespace in the CSV:

>>> '    ,'.split(',')
['    ', '']
>>> '     ,val'.split(',')
['     ', 'val'] 
dawg
  • 98,345
  • 23
  • 131
  • 206