473,396 Members | 1,797 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

newbie question: for loop within for loop confusion

Hi,

I'm studying python via the exellent book "How to think like a python
programmer" by Allen Downey.

Noob question follows...

animals.txt is a list of animals, each on a separate line: "aardvard,
bat, cat, dog, elephant, fish, giraffe, horse, insect, jackelope"

I want to loop through the list of words and print words that don't
have any "avoid" letter in them.

def hasnolet(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()
for letter in avoid:
if letter in word:
break
else:
print word

hasnolet('abcd')

Why doesn't the function above work? It returns:

dog
dog
dog
fish
fish
fish
fish
horse
horse
horse
horse
inchworm
inchworm
thanks for any help.

takayuki
Jun 27 '08 #1
17 1456
In article
<a0**********************************@g16g2000pri. googlegroups.com>,
takayuki <la********@gmail.comwrote:
Hi,

I'm studying python via the exellent book "How to think like a python
programmer" by Allen Downey.

Noob question follows...

animals.txt is a list of animals, each on a separate line: "aardvard,
bat, cat, dog, elephant, fish, giraffe, horse, insect, jackelope"

I want to loop through the list of words and print words that don't
have any "avoid" letter in them.

def hasnolet(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()
for letter in avoid:
if letter in word:
break
else:
print word

hasnolet('abcd')
I could give you a fish, or I could teach you to fish. I'd rather do the
latter. So...

Take your inner loop:
for letter in avoid:
if letter in word:
break
else:
print word
and instrument it so you can see exactly what's happening. Try something
like:
for letter in avoid:
print "letter = %s" % letter
if letter in word:
print "it's in word"
break
else:
print "no it's not"
print word
and see if that helps.
Jun 27 '08 #2
On 09:23, lunedì 16 giugno 2008 takayuki wrote:
word = line.strip()
Try
word= line.split()

and at the end of the loop add one more print to go to new line.
--
Mailsweeper Home : http://it.geocities.com/call_me_not_now/index.html
Jun 27 '08 #3
takayuki wrote:

for letter in avoid:
if letter in word:
break
else:
print word
Take the word 'dog', for example. What the above loop is doing is
basically this:

1. for letter in avoid uses 'a' first
2. is 'a' in 'dog'?
3. no, so it prints 'dog'
4. go back to for loop, use 'b'
5. is 'b' in 'dog'?
6. no, so it prints 'dog' again
7. go back to for loop.....

Since it goes sequentially through 'abcd', it will say that the first
three letters are not in 'dog', and therefore print it three times. Then
it finally sees that 'd' *is* in dog, so it skips it the fourth time
through the loop.
Jun 27 '08 #4
takayuki wrote:
inchworm
inchworm
P.S. Why does 'inchworm' only print twice? Or is that not the full output?
Jun 27 '08 #5
Thanks to everyone for the excellent advice.

Roy: I did as you suggested and could see after staring at the output
for awhile what was going on. The print statements really helped to
put a little light on things. Yes, I agree that "learning to fish" is
the best way.

John: There were two "inchworms" because "c" is in "inchworm" so it
shouldn't print. Thanks for your detailed description of the for
loop.

The Saint: i'll check out the word = line.split() command.
After much flailing about, here's a loop that is working:

def hasnolet2(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()

length = len(avoid)
x = 0
noprint = 0

while length -1 >= x:
if avoid[x] in word:
noprint = noprint + 1
x = x + 1

if noprint == 0:
print word

hasnolet2('abcd')

which should return:
fish
horse
hasnolet2('abcd')
Jun 27 '08 #6
On Jun 16, 2:35*pm, takayuki <lawtonp...@gmail.comwrote:
def hasnolet2(avoid):
* * * * fin = open('animals.txt')
* * * * for line in fin:
* * * * * * * * word = line.strip()

* * * * length = len(avoid)
* * * * x = 0
* * * * noprint = 0

* * * * while length -1 >= x:
* * * * * * * * if avoid[x] in word:
* * * * * * * * * * * * noprint = noprint + 1
* * * * * * * * x = x + 1

* * * * if noprint == 0:
* * * * * * * * print word
There seems to be an indendation problem (presumably the code from
length = len(avoid) onwards should be inside the loop). But apart from
that, we can try to make this more 'pythonic'.

First, python has a 'for' statement that's usually better than using
while. We use the 'range' function that produces the numbers 0, 1, ...
length - 1, and x takes the value of these in turn.

Here's the last bit of your code rewritten like this:

noprint = 0

for x in range(length):
if avoid[x] in word:
noprint += 1

if noprint == 0:
print word

But better, rather than using 'x' as an index, we can loop over
letters in avoid directly. I've changed 'noprint' to be a boolean
'should_print' too here.

should_print = True
for letter in avoid:
if letter in word:
should_print = False

if should_print:
print word

We can eliminate 'should_print' completely, by using 'break' and
'else'. A break statement in a loop causes the loop to end. If the
loop doesn't break, the 'else' code is run when the loop's over.

for letter in avoid:
if letter in word:
break
else:
print word

This is almost the same as your original code, but the 'else' is
attached to the 'for' rather that the 'if'!

Finally, in Python 2.5 you can write this:

if not any(letter in word for letter in avoid):
print word

I think this is the best solution, as it's readable and short.

--
Paul Hankin
Jun 27 '08 #7
"takayuki" <la********@gmail.comwrote in message
news:ba**********************************@g16g2000 pri.googlegroups.com...
John: There were two "inchworms" because "c" is in "inchworm" so it
shouldn't print. Thanks for your detailed description of the for
loop.
lol, I even sat there looking at the word and said to myself "ok, it doesn't
contain any of the four letters" :)
Jun 27 '08 #8
"takayuki" <la********@gmail.comwrote in message
news:a0**********************************@g16g2000 pri.googlegroups.com...
fin = open('animals.txt')
for line in fin:
You can write this as:

for line in open('animals.txt'):
#do stuff

Of course, you can't explicitly close the file this way, but that probably
doesn't matter. Another way, I think, is to wrap the for loops in this:

with open('animals.txt') as file:
#for loop stuff here
Jun 27 '08 #9
On Jun 16, 7:17 am, Paul Hankin <paul.han...@gmail.comwrote:
On Jun 16, 2:35 pm, takayuki <lawtonp...@gmail.comwrote:
def hasnolet2(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()
length = len(avoid)
x = 0
noprint = 0
while length -1 >= x:
if avoid[x] in word:
noprint = noprint + 1
x = x + 1
if noprint == 0:
print word

There seems to be an indendation problem (presumably the code from
length = len(avoid) onwards should be inside the loop). But apart from
that, we can try to make this more 'pythonic'.

First, python has a 'for' statement that's usually better than using
while. We use the 'range' function that produces the numbers 0, 1, ...
length - 1, and x takes the value of these in turn.

Here's the last bit of your code rewritten like this:

noprint = 0

for x in range(length):
if avoid[x] in word:
noprint += 1

if noprint == 0:
print word

But better, rather than using 'x' as an index, we can loop over
letters in avoid directly. I've changed 'noprint' to be a boolean
'should_print' too here.

should_print = True
for letter in avoid:
if letter in word:
should_print = False

if should_print:
print word

We can eliminate 'should_print' completely, by using 'break' and
'else'. A break statement in a loop causes the loop to end. If the
loop doesn't break, the 'else' code is run when the loop's over.

for letter in avoid:
if letter in word:
break
else:
print word

This is almost the same as your original code, but the 'else' is
attached to the 'for' rather that the 'if'!

Finally, in Python 2.5 you can write this:

if not any(letter in word for letter in avoid):
print word

I think this is the best solution, as it's readable and short.
Alternatively, you could use sets:

if not(set(word) & set(avoid)):
print word

(parentheses added for clarity.)
Jun 27 '08 #10
On Jun 15, 6:23 pm, takayuki <lawtonp...@gmail.comwrote:
def hasnolet(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()
for letter in avoid:
if letter in word:
break
else:
print word
You're using the split command correctly, but you're not filtering
correctly. Consider this:

---begin---
fin = open('animals.txt')
"\n".join(["%s" % line for line in fin if len(line.strip('abcd')) ==
len(line)])
----end----

Let's go slow.

"\n".join([...])

1. Take everything that is in the following list, and print each one
with a carriage return appended to it.

"\n".join(["%s" % line for line in fin ...])

2. For each line in fin, create a string that only consists of what
currently in the line variable, using string substitution.

"\n".join(["%s" % line for line in fin if len(line.strip('abcd')) ==
len(line)])

3. Only do #2 if the length of the line after stripping out the
unnecessary characters is the same length as the line originally. This
way we filter out the lines we don't want. If we wanted the lines that
have been filtered, we can change "==" to "!=" or "<=".

Now, I read "Dive Into Python" first, which through these early on in
the book. If your eyes cross looking at this, write it down and read
it again after you get a little farther into the book you're reading
Jun 27 '08 #11
On Jun 16, 2:34 pm, Thomas Hill <tomlikestor...@gmail.comwrote:
On Jun 15, 6:23 pm, takayuki <lawtonp...@gmail.comwrote:
def hasnolet(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()
for letter in avoid:
if letter in word:
break
else:
print word

You're using the split command correctly, but you're not filtering
correctly. Consider this:

---begin---
fin = open('animals.txt')
"\n".join(["%s" % line for line in fin if len(line.strip('abcd')) ==
len(line)])
----end----

Let's go slow.

"\n".join([...])

1. Take everything that is in the following list, and print each one
with a carriage return appended to it.

"\n".join(["%s" % line for line in fin ...])

2. For each line in fin, create a string that only consists of what
currently in the line variable, using string substitution.

"\n".join(["%s" % line for line in fin if len(line.strip('abcd')) ==
len(line)])

3. Only do #2 if the length of the line after stripping out the
unnecessary characters is the same length as the line originally. This
way we filter out the lines we don't want. If we wanted the lines that
have been filtered, we can change "==" to "!=" or "<=".

Now, I read "Dive Into Python" first, which through these early on in
the book. If your eyes cross looking at this, write it down and read
it again after you get a little farther into the book you're reading
Guh, no, I'm reading the description of strip wrong. Fooey. Anyone
else able to one line it?
Jun 27 '08 #12
Paul,

Thank you for the informative reply.

Yes, I created the indent problem when manually copying the original
script when I posted. (I'm using an old laptop to study python and
posting here using the desktop.)

Your examples really helped. Last night I played with using a for
loop instead of a while loop and got it working, but your examples
really clarified things.

This loop was particularly interesting because I didn't know the else
could be attached to the for. Attaching it to the for solved a lot of
problems.

for letter in avoid:
if letter in word:
break
else:
print word
I've printed out this whole thread and will be playing with your and
others' solutions.

I love this one for its conciseness, but will have to play with it to
get my head around it.

if not any(letter in word for letter in avoid):
print word

Thanks again.

takayuki
Jun 27 '08 #13
On Jun 17, 6:34 am, Thomas Hill <tomlikestor...@gmail.comwrote:
On Jun 15, 6:23 pm, takayuki <lawtonp...@gmail.comwrote:
def hasnolet(avoid):
fin = open('animals.txt')
for line in fin:
word = line.strip()
for letter in avoid:
if letter in word:
break
else:
print word

You're using the split command correctly, but you're not filtering
correctly. Consider this:

---begin---
fin = open('animals.txt')
"\n".join(["%s" % line for line in fin if len(line.strip('abcd')) ==
len(line)])
----end----

Let's go slow.

"\n".join([...])

1. Take everything that is in the following list, and print each one
with a carriage return appended to it.

"\n".join(["%s" % line for line in fin ...])

2. For each line in fin, create a string that only consists of what
currently in the line variable, using string substitution.

"\n".join(["%s" % line for line in fin if len(line.strip('abcd')) ==
len(line)])

3. Only do #2 if the length of the line after stripping out the
unnecessary characters is the same length as the line originally. This
way we filter out the lines we don't want. If we wanted the lines that
have been filtered, we can change "==" to "!=" or "<=".

Now, I read "Dive Into Python" first, which through these early on in
the book. If your eyes cross looking at this, write it down and read
it again after you get a little farther into the book you're reading
Thomas,

thanks for the reply.

I'm early on in my python adventure so I'm not there yet on the strip
command nuances. I'm reading "How to think like a python
programmer" first. It's great.

Then "Learning python". I've read parts of Dive into Python and will
work through it fully when I'm a little farther along.

takayuki
Jun 27 '08 #14
takayuki wrote:
I'm early on in my python adventure so I'm not there yet on the strip
command nuances. I'm reading "How to think like a python
programmer" first. It's great.

Then "Learning python". I've read parts of Dive into Python and will
work through it fully when I'm a little farther along.
Yeah, I really recommend Learning Python for getting the basics first.
It's very thorough in that regard. Dive Into Python is *not* for
beginners. I'm sorry if people disagree, but it's just not.
Jun 27 '08 #15
takayuki wrote:
Paul,

Thank you for the informative reply.

Yes, I created the indent problem when manually copying the original
script when I posted. (I'm using an old laptop to study python and
posting here using the desktop.)

Your examples really helped. Last night I played with using a for
loop instead of a while loop and got it working, but your examples
really clarified things.

This loop was particularly interesting because I didn't know the else
could be attached to the for. Attaching it to the for solved a lot of
problems.

for letter in avoid:
if letter in word:
break
else:
print word
I've printed out this whole thread and will be playing with your and
others' solutions.

I love this one for its conciseness, but will have to play with it to
get my head around it.

if not any(letter in word for letter in avoid):
print word

Thanks again.

takayuki
--
http://mail.python.org/mailman/listinfo/python-list
takayuki,

Could you post the complete script.
thanks
david
--
Powered by Gentoo GNU/LINUX
http://www.linuxcrazy.com

Jun 27 '08 #16
En Mon, 16 Jun 2008 22:51:30 -0300, John Salerno <jo******@gmailNOSPAM.comescribió:
takayuki wrote:
>I'm early on in my python adventure so I'm not there yet on the strip
command nuances. I'm reading "How to think like a python
programmer" first. It's great.

Then "Learning python". I've read parts of Dive into Python and will
work through it fully when I'm a little farther along.

Yeah, I really recommend Learning Python for getting the basics first.
It's very thorough in that regard. Dive Into Python is *not* for
beginners. I'm sorry if people disagree, but it's just not.
Sure, the author himself says so at the very beginning in http://www.diveintopython.org "Dive Into Python is a Python book for experienced programmers."

--
Gabriel Genellina

Jun 27 '08 #17
Gabriel Genellina wrote:
En Mon, 16 Jun 2008 22:51:30 -0300, John Salerno <jo******@gmailNOSPAM.comescribió:
>takayuki wrote:
>>I'm early on in my python adventure so I'm not there yet on the strip
command nuances. I'm reading "How to think like a python
programmer" first. It's great.

Then "Learning python". I've read parts of Dive into Python and will
work through it fully when I'm a little farther along.
Yeah, I really recommend Learning Python for getting the basics first.
It's very thorough in that regard. Dive Into Python is *not* for
beginners. I'm sorry if people disagree, but it's just not.

Sure, the author himself says so at the very beginning in http://www.diveintopython.org "Dive Into Python is a Python book for experienced programmers."
I know, but I just hear so many people recommend that book for people
who want to learn the language.
Jun 27 '08 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Steve Macleod | last post by:
Hi there, Newbie at this, so here goes: I am attempting to build a page that updates multiple records. The page uses as its input, a series of dynamically generated text boxes from the...
11
by: Wayne Folta | last post by:
Two observations about PEP-315: 1. It's clever, addresses a definite "wart", and is syntactically similar to try/except. But it's syntax seems like an acquired taste to me. 2. It is a very...
20
by: __PPS__ | last post by:
Hello everybody in a quiz I had a question about dangling pointer: "What a dangling pointer is and the danger of using it" My answer was: "dangling pointer is a pointer that points to some...
14
by: Crimsonwingz | last post by:
Need to calculate a sum based on a number of factors over a period of years. I can use formula ^x for some of it, but need totals to carry over in the sum and have only been able to do this thus...
5
by: Blankdraw | last post by:
I can't get this nested loop to break the outer loop at the 5th data value so control can proceed to the next array col and continue pigeon-holing the next 5 in its own column. Why can I not get...
2
by: takayuki | last post by:
Hi everyone, I'm studying python via the excellent "how to think like a python programmer" book by Allen Downey. Noob question follows... I have a txt file (animals.txt) which contains the...
7
by: idiolect | last post by:
Hi all - Sorry to plague you with another newbie question from a lurker. Hopefully, this will be simple. I have a list full of RGB pixel values read from an image. I want to test each RGB band...
12
by: Philipp.Weissenbacher | last post by:
Hi all! This is most certainly a total newbie question, but why doesn't the following code cause a segfault? void insertion_sort(int a, int length) { int i; for (i=0; i < length; i++) { int...
0
by: xrxst32 | last post by:
Hello there, I have some doubts about the best practice for using COM automation, the Runtime Callable Wrapper (RCW) and Marshal.ReleaseComObject. So the question is/are: Do I need to release...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.