lists and list item matches (ghost wodgame)

nn pruebauno at latinmail.com
Fri Sep 24 15:14:22 CEST 2010


On Sep 23, 8:46 pm, Baba <raoul... at gmail.com> wrote:
> On Sep 23, 8:13 pm, nn <prueba... at latinmail.com> wrote:
>
>
>
> > On Sep 23, 1:25 pm, Baba <raoul... at gmail.com> wrote:
>
> > > On Sep 23, 4:17 pm, nn <prueba... at latinmail.com> wrote:
>
> > > > On Sep 23, 10:56 am, nn <prueba... at latinmail.com> wrote:
>
> > > > > On Sep 22, 6:39 pm, Baba <raoul... at gmail.com> wrote:
>
> > > > > > On Sep 22, 9:18 pm, Baba <raoul... at gmail.com> wrote:
>
> > > > > > > On Sep 22, 3:38 pm, nn <prueba... at latinmail.com> wrote:
>
> > > > > > > > On Sep 21, 6:39 pm, Baba <raoul... at gmail.com> wrote:
>
> > > > > > > > > Hi
>
> > > > > > > > > query level: beginner
>
> > > > > > > > > as part of a learning exercise i have written code that:
>
> > > > > > > > > a) asks for a single letter input (assumption: only 1 letter wil be
> > > > > > > > > entered)
> > > > > > > > > b) adds that letter to list1 and then goes through list2 and checks:
>
> > > > > > > > >     1) if any item in list2 starts with list1 > if False: break
> > > > > > > > >     2) if list1 == any item in list2 > if True: break
>
> > > > > > > > > c) start again until 2) is True
>
> > > > > > > > > wordlist = ['hello', 'bye']
> > > > > > > > > handlist = []
> > > > > > > > > letter = raw_input('enter letter: ')
> > > > > > > > > handlist.append(letter)
> > > > > > > > > hand = "".join(handlist)
> > > > > > > > > for item in wordlist:
> > > > > > > > >     if item.startswith(hand):
> > > > > > > > >         while item.startswith(hand):
> > > > > > > > >             if hand not in wordlist:
> > > > > > > > >                 letter = raw_input('enter letter: ')
> > > > > > > > >                 handlist.append(letter)
> > > > > > > > >                 hand = "".join(handlist)
> > > > > > > > >             else: break
> > > > > > > > >         else: break
> > > > > > > > > print 'you loose'
>
> > > > > > > > > this code works but can it be optimised? i have the feeling that my
> > > > > > > > > nesting of IF, WHILE and FOR statements is overkill?
>
> > > > > > > > > inspired by part IV ofhttp://ocw.mit.edu/courses/electrical-engineering-and-computer-scienc...
>
> > > > > > > > > thanks
> > > > > > > > > Baba
>
> > > > > > > > Yes it is overkill. Especially the else:break from the while loop
> > > > > > > > makes it difficult to follow the logic. Also the program breaks down
> > > > > > > > if I use the following word list:
>
> > > > > > > > wordlist = ['hello', 'hamburger', 'bye']
>
> > > > > > > > enter letter: h
> > > > > > > > enter letter: a
> > > > > > > > you loose
>
> > > > > > > > I am not going to post any spoilers but I wrote your program using one
> > > > > > > > while loop and one generator expression for a total of 5 lines. My
> > > > > > > > version might be a bit too advanced but you should still be able to do
> > > > > > > > it using only one while, one for and one if instead.
>
> > > > > > > Hi nn,
>
> > > > > > > i wasn't expecting my code to fail with an additional word in it.
> > > > > > > While i was conscious that the whole construct was heavy i thought the
> > > > > > > reasoning worked. I keep looking at it but can't figure out the
> > > > > > > problem Can you give me a hint?
>
> > > > > > > In the meantime i found out that it is actually possible to populate a
> > > > > > > string (just like a list, a dictionary or a tuple). Here's what i've
> > > > > > > got now:
>
> > > > > > > wordlist = ['hello', 'bye']
> > > > > > > hand = ''
> > > > > > > for item in wordlist:
> > > > > > >     if item.startswith(hand):
> > > > > > >         while item.startswith(hand):
> > > > > > >             if hand not in wordlist:
> > > > > > >                 hand += raw_input('enter letter: ')
> > > > > > >                 print hand
> > > > > > >             else: break
> > > > > > >         else: break
> > > > > > > print 'you loose'
>
> > > > > > > But i can't figure out why it won't work when adding the extra word.
> > > > > > > Thanks by the way, it taught me not to be too confident when things
> > > > > > > SEEM to work...
>
> > > > > > > Why does it work when i use the built-in function any(iterable)?? To
> > > > > > > me using the any(iterable) function seems just like regrouping 3 lines
> > > > > > > into one...
>
> > > > > > > wordlist = ['hello','hamburger', 'bye', 'cello']
> > > > > > > hand = ''
> > > > > > > while any(item.startswith(hand) for item in wordlist):
> > > > > > >     if hand not in wordlist:
> > > > > > >         hand += raw_input('enter letter: ')
> > > > > > >     else: break
> > > > > > > print 'you loose'
>
> > > > > > > thanks
>
> > > > > > > Baba
>
> > > > > > Hi nn,
>
> > > > > > looking at my original code again i realise that having a raw_input
> > > > > > inside a FOR loop is flawed per se (at least for my purposes) so i
> > > > > > will just assume that i was taking the wrong approach initially. No
> > > > > > point in analysing it further. Thanks for your help.
>
> > > > > > Baba
>
> > > > > Since you seem to have figured it out I will post my version (python
> > > > > 3):
>
> > > > > wordlist = ['hello', 'hamburger', 'bye']
> > > > > inp=''
> > > > > while any(word.startswith(inp) and word!=inp for word in wordlist):
> > > > >     inp += input('enter letter: ')
> > > > > print('you lose')
>
> > > > > The reason why your original version didn't work was because each time
> > > > > you add a letter you have to go again over all words (in reality only
> > > > > a subset is required) and find a new one. Your version would find one
> > > > > word using the first letter and then exit.
>
> > > > Actually my version isn't right (for some values of right):
>
> > > > wordlist = ['hello', 'hamburger', 'bye']
> > > > inp=''
> > > > while any(word.startswith(inp) for word in wordlist) and (inp not in
> > > > wordlist):
> > > >     inp += input('enter letter: ')
> > > > print('you lose')
>
> > > > An explanation of how this changes the rules of the wordgame is left
> > > > as an exercise to the reader.
>
> > > Hi,
>
> > > for now i will stick to Python2.7 but thank you for sharing.
>
> > > for learning purposes i still want to figure out a way to solve this
> > > without built-in function ('any' in this case). My understanding was
> > > that in programming almost anything can be done with IF, FOR and WHILE
> > > statements. However i turn in circles...:( i understand that in my
> > > original code my while loop locked me into the first word hello if the
> > > first letter was 'h' and therefore if the next letter was 'a' it would
> > > break...so far so good but this appears really tricky to solve...here
> > > is what i have come up with but it will not exit if for example i
> > > enter 'x' ...
>
> > > wordlist = ['hello', 'bye']
> > > hand = ''
> > > while hand not in wordlist:
> > >     hand += raw_input('enter letter: ')
> > >     print hand
> > >     for item in wordlist:
> > >         if not item.startswith(hand):
> > >             break
> > > print 'you lose'
>
> > > but no matter how i turn this around i can't find the magic
> > > approach...i was thinking about starting the code with something like
> > > "while (something) is True" ... would that be a right approach?
>
> > > Baba
>
> > This program has 2 problems:
> > 1.) the break only exits one level: i.e. the for loop
> > 2.) your logic is backwards. You stop checking as soon as you find the
> > first mismatch. It should be the other way around: it is invalid only
> > after testing with all words and not finding any match.
>
> > And yes all of this can be done using just using while, for and if. I
> > just wrote another version with 1 while, 1 for, 2 ifs, 0 breaks, 0
> > any, 0 genexp. This is like doing algebra: you add 2 here, substract 2
> > there and the same result comes out. There is an infinite number of
> > programs that can be written to generate the same output.
>
> wordlist = ['hello', 'hamburger', 'bye', 'foo']
> hand = ''
> check = True
> while check == True:
>     check = False
>     hand += raw_input('enter letter: ')
>     for item in wordlist:
>         if item.startswith(hand):
>             check = True
>             break
>     if hand in wordlist:
>         break
> print 'you lose'
>
> learning objective achieved :) Thanks for your help!
>
> Baba

You are welcome. Just for completeness I post my version too:

wordlist = ['hello', 'ham', 'hamburger', 'bye']
hand = ''
found_start = not_word = True
while found_start and not_word:
    hand += input('enter letter: ')
    found_start = not_word = False
    for word in wordlist:
        if word.startswith(hand):
            found_start = True
    if hand not in wordlist:
        not_word = True
print('you lose')



More information about the Python-list mailing list