2

I'm reading a file line by line, and I've separated it out with line.split(',') the way I want to. Now I want to flag, copy to list, or perform a function on:

A line which contains the string 'THIS', but not 'THAT'.

I'm shooting for something that looks like this:

if any(('THIS' in s for s in csvLine) if any('THAT' **!in** s for s in csvLine):
        print csvLine

but this isn't good syntax at all. I think I'm in over my head using list comprehension, but I have successfully done it before thanks to this answer.

I do have a working solution with the code below, but I sense there's something better:

    if any('THAT' in s for s in csvLine):
        print "do nothing"
    elif any('THIS' in s for s in csvLine):
        print "do something"
    else:
        print "do nothing"

How do I compress the logic of these if-else statements into more beautiful, pythonic, code?

This is my actual, not-generalized, plain English question: if a line contains CHAT and TRANSFER, then it is unimportant. If it contains only CHAT, it is unimportant. If it contains just TRANSFER and not the word CHAT, it is noteworthy and I want to do something with the line. How to I find the lines with the word TRANSFER, but not CHAT in them?

Community
  • 1
  • 1
emmagras
  • 1,378
  • 2
  • 18
  • 25

3 Answers3

4

Not sure if I fully understand - why do you need to iterate through the line? This seems like it would work better:

if 'this' in csvLine and not 'that' in csvLine:
    do_something()
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • I thought I needed to iterate through the whole line because I had separated it for use later, but this works for separated stuff as well. I didn't know the syntax for "and not" until now. Thanks – emmagras Jun 11 '12 at 19:10
  • To avoid potential order-of-operations confusion, I would use `if 'this' in csvLine and 'that' not in csvLine`, though the example given evaluates correctly. – Casey Kuball Jun 11 '12 at 19:15
  • I'm accepting this with @Darthfett 's adjustment because it does quite simply what I need it to. I wouldn't have used any() if I could have avoided it, anyway. – emmagras Jun 11 '12 at 19:23
1
if any('THIS' in s for s in csvLine) and all('THAT' not in s for s in csvLine):

is the same as

if any('THIS' in s for s in csvLine) and not any('THAT' in s for s in csvLine):

The 'THIS' part will stop iterating as soon as 'THIS' is found and the 'THAT' will stop iterating as soon as 'THAT' is found. It is possible, that one or both of the iterations will have to complete.

eumiro
  • 207,213
  • 34
  • 299
  • 261
  • The second line here is exactly what I was looking for (though @Daniel's answer may indicate I'm being too verbose with this line of thought). How does the "all('THAT not in s" function? Can someone direct me to where I can read more about the 'any' and 'all' things? I don't know the vocabulary terms for what they even are. – emmagras Jun 11 '12 at 19:15
1

From the question you linked to, make a slight modification:

csv_line = ["Has CHAT", "Has TRANSFER", "Has CHAT and TRANSFER"]
transfers = [s for s in csv_line if "TRANSFER" in s and "CHAT" not in s]
print transfers

>>> ['Has TRANSFER']
kaveman
  • 4,339
  • 25
  • 44
  • This tests individual elements of the list, not the list as whole. – eumiro Jun 11 '12 at 19:03
  • Not sure I understand the comment? OP wants lines with "TRANSFER" and not "CHAT", this builds such a list of lines – kaveman Jun 11 '12 at 19:04
  • see his "working solution". With your `some_list` he wants to do nothing, because it contains 'CHAT'. – eumiro Jun 11 '12 at 19:06
  • `some_list` is assumed to be the result of OP's call to `line.split()`, the contents of a line. I was a little confused and my name choices weren't the best, but I think it's still valid. (Edited to reflect this) – kaveman Jun 11 '12 at 19:10