Reputation: 35
I have the following code:
fhand=open('mbox-short.txt')
count=0
for line in fhand:
words=line.split()
print(words)
if len(words)==0: continue
if words[0]!='From': continue
print(words[2])
This code prints a valid output (I am trying to get the day of a sent email from a mbox.txt file). When I try to combine the two "if" statements as follows:
if words[0]!='From' and len(words)==0: continue
I get this error:
['From', '[email protected]', 'Sat', 'Jan', '5', '09:14:16', '2008']
Sat
['Return-Path:', '<[email protected]>']
Traceback (most recent call last):
File "untitled.py", line 7, in <module>
print(words[2])
IndexError: list index out of range
I see that the issue occurs at the Return-Path line but why is it taken into consideration? And shouldn't the combined if statement have the same output as the two separated if statements?
Upvotes: 0
Views: 148
Reputation: 91017
The differing output shows that the two solutions are not equivalent: you chose the wrong operator.
What happens in the original? If the fist condition is met, continue
is executed. If not, the second one is tested and the loop continue
d as appropriate.
This behaviour is relicated by one operator. but this is the or
operator. And if you do it in the right order, everthing works as wanted:
if len(words)==0 or words[0]!='From': continue
Let's look what happens: the first part of the condition is executed. If len(words)==0
is true, the second half is skipped (this is called short-circuiting) and the loop continue
d. This is good, as words[0]
would lead to an error if evaluated despite the length being 0.
Only if the length is not 0, the second test is performed.
Note that there are several ways of testing a list for emptiness:
len(words) == 0
not len(words)
not words
Both of these expressions are True
if the list is empty and False
if not.
Upvotes: 2
Reputation: 9969
The issue you're having is that you flipped the order of your tests. You're now testing the length after attempting to check what the first value is:
if words[0]!='From' and len(words)==0: continue
Python checks conditions from left to right, so it will first check if words[0]!='From'
and then test len(words)==0
, however if words
is empty then the first test tries to access a non existent index and creates your error.
You need to use this order instead and use the or
operator as deceze pointed out, because you only care if one of these is True
, not both.
if len(words)==0 or words[0]!='From': continue
Upvotes: 2