Rita Sue and Bob too

Discussion in 'Python' started by M. Clift, Aug 20, 2004.

  1. M. Clift

    M. Clift Guest

    Hi All,

    Can someone help. I promise I've looked how to do this but can't find a
    way...

    Ok, to find one name is easy

    if 'Bob' in list:
    print "They were found"
    else:
    print "They are not in list"

    But, how to I find a sequence in a list of unknown size? i.e. this sequence
    in list of other names and replace it with three others?

    'Rita','Sue','Bob'

    This is almost a nightly occurrence (my posting questions), but I am
    learning : )
     
    M. Clift, Aug 20, 2004
    #1
    1. Advertising

  2. M. Clift

    Peter Hansen Guest

    M. Clift wrote:
    > Hi All,
    >
    > Can someone help. I promise I've looked how to do this but can't find a
    > way...
    >
    > Ok, to find one name is easy
    >
    > if 'Bob' in list:
    > print "They were found"
    > else:
    > print "They are not in list"
    >
    > But, how to I find a sequence in a list of unknown size? i.e. this sequence
    > in list of other names and replace it with three others?
    >
    > 'Rita','Sue','Bob'
    >
    > This is almost a nightly occurrence (my posting questions), but I am
    > learning : )


    My first thought would be to scan the list for the first element
    'Rita', and when you find it, take out a slice that is the
    same size as the sequence you have there (use len() of course)
    and compare the two. If they don't match, move on. The scanning
    and "moving on" part would certainly best be done using .index()
    and note that that function can take a second parameter which
    specifies the starting index, so you can do a progressive search
    efficiently. The actual code is left as an exercise to the
    reader. ;-)

    -Peter
     
    Peter Hansen, Aug 20, 2004
    #2
    1. Advertising

  3. M. Clift

    Jeremy Jones Guest

    M. Clift wrote:

    >Hi All,
    >
    >Can someone help. I promise I've looked how to do this but can't find a
    >way...
    >
    >Ok, to find one name is easy
    >
    >if 'Bob' in list:
    > print "They were found"
    >else:
    > print "They are not in list"
    >
    >But, how to I find a sequence in a list of unknown size? i.e. this sequence
    >in list of other names and replace it with three others?
    >
    >'Rita','Sue','Bob'
    >
    >This is almost a nightly occurrence (my posting questions), but I am
    >learning : )
    >
    >
    >
    >

    I'm sure someone else can come up with something more elegant, but
    here's a way you could do it:

    >>> names

    ['larry', 'curly', 'moe', 'shimp', 'rita', 'sue', 'bob', 'billy', 'scott']
    >>> for idx in range(len(names)):

    .... if names[idx:idx + 3] == ['sue', 'bob', 'billy']:
    .... print "found 'em at element", idx
    .... break
    ....
    found 'em at element 5
    >>>


    Notice, this:
    >>> ['sue', 'bob', 'billy'] in names

    False
    >>>

    returns false. The reason is, I think, because the set ['sue', 'bob',
    'billy'] is not really a subset of ['larry', 'curly', 'moe', 'shimp',
    'rita', 'sue', 'bob', 'billy', 'scott'], even though the three names
    appear sequentially in both lists. But, this:

    >>> names2

    [['sue', 'bob', 'billy'], ['larry', 'curly', 'moe', 'shimp', 'rita',
    'sue', 'bob', 'billy', 'scott']]
    >>> ['sue', 'bob', 'billy'] in names2

    True
    >>>

    does "work" for the same reason that it doesn't work in the first
    example. The list ['sue', 'bob', 'billy'] itself is part of the larger
    list, names2.

    HTH,

    Jeremy Jones
     
    Jeremy Jones, Aug 20, 2004
    #3
  4. M. Clift

    Paul Rubin Guest

    "M. Clift" <> writes:
    > But, how to I find a sequence in a list of unknown size? i.e. this sequence
    > in list of other names and replace it with three others?
    >
    > 'Rita','Sue','Bob'
    >
    > This is almost a nightly occurrence (my posting questions), but I am
    > learning : )


    You have to scan through the list and look for that sequence, e.g.

    for i in xrange(len(mylist) - 2):
    if mylist[i:i+3] == ['Rita','Sue','Bob']:
    print 'They were found'
    break

    There are fancier and more efficient ways to scan the list, but this
    is the basic idea.
     
    Paul Rubin, Aug 20, 2004
    #4
  5. M. Clift

    M. Clift Guest

    Thankyou to all of you, and so quick.

    More for me to study : )

    All the best,

    M
     
    M. Clift, Aug 20, 2004
    #5
  6. M. Clift

    Eugene Oden Guest

    M. Clift wrote:

    > Hi All,
    >
    > Can someone help. I promise I've looked how to do this but can't find a
    > way...
    >
    > Ok, to find one name is easy
    >
    > if 'Bob' in list:
    > print "They were found"
    > else:
    > print "They are not in list"
    >
    > But, how to I find a sequence in a list of unknown size? i.e. this
    > sequence in list of other names and replace it with three others?
    >
    > 'Rita','Sue','Bob'
    >
    > This is almost a nightly occurrence (my posting questions), but I am
    > learning : )


    here's my stab at it:

    def findSequence(seq, search):
    """returns the index where search can be found in seq where search and
    seq are both sequences.
    """
    searchLength = len(search)

    for i in range(len(seq)-searchLength+1):
    compare = seq[i:i+searchLength+1]

    if search == seq[i:i+searchLength]:
    return i

    raise ValueError, 'sequence %s is not in list' % str(search)

    someList = ['Joe', 'Rita', 'Sue', 'Bob', 'Peter']
    searchList = ['Rita', 'Sue', 'Bob']

    i = findSequence(someList, searchList)
    someList[i:i+len(searchList)] = ['Paul', 'John', 'James']
    # someList is now ['Joe', 'Paul', 'John', 'James', 'Peter']

    findSequence(someList, searchList) # raises ValueError
     
    Eugene Oden, Aug 20, 2004
    #6
  7. M. Clift wrote:

    > But, how to I find a sequence in a list of unknown size? i.e. this
    > sequence in list of other names and replace it with three others?


    How about a generator?

    def slice(apple, worm, new_worm):
    while apple:
    if worm == apple[:len(worm)]:
    apple = apple[len(worm):]
    yield new_worm
    else:
    yield [apple.pop(0)]

    Jeffrey
     
    Jeffrey Froman, Aug 20, 2004
    #7
  8. Jeffrey Froman wrote:
    > How about a generator?


    Sorry, bad paste on my previous reply. The generator example should look
    like:

    def replace_in_list(apple, worm, new_worm):
    while apple:
    if worm == apple[:len(worm)]:
    apple = apple[len(worm):]
    for w in new_worm:
    yield w
    else:
    yield apple.pop(0)
     
    Jeffrey Froman, Aug 20, 2004
    #8
  9. In article <cg3ksb$bg5$>,
    "M. Clift" <> wrote:

    > Hi All,
    >
    > Can someone help. I promise I've looked how to do this but can't find a
    > way...
    >
    > Ok, to find one name is easy
    >
    > if 'Bob' in list:
    > print "They were found"
    > else:
    > print "They are not in list"
    >
    > But, how to I find a sequence in a list of unknown size? i.e. this sequence
    > in list of other names and replace it with three others?
    >
    > 'Rita','Sue','Bob'
    >
    > This is almost a nightly occurrence (my posting questions), but I am
    > learning : )


    You've gotten several other answers, but I'd like to propose yet another
    one:

    def replace_sublist(L, S, T):
    """Replace each sublist of L equal to S with T. Also returns the
    resulting list."""

    assert(len(S) == len(T))

    for p in [ x for x in xrange(len(L))
    if L[x] == S[0] and L[x : x + len(S)] == S ]:
    L[p : p + len(S)] = T

    return L

    In short, the list comprehension gives all the offsets in L where a copy
    of S can be found as a sublist. Now, if it happens that some of these
    positions overlap (e.g., L = [ 1, 1, 1 ] and S = [ 1, 1 ]), then the
    results will be strange. But as long as your matches do not overlap,
    this should work well.

    -M

    --
    Michael J. Fromberger | Lecturer, Dept. of Computer Science
    http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA
     
    Michael J. Fromberger, Aug 20, 2004
    #9
  10. M. Clift

    M. Clift Guest

    If I wasn't happy enough already with the examples/ideas you've all shown
    me, how about searching as previously, but where the middle name could be
    anything. i.e. 'Rita', 'anyname','Bob'

    M
     
    M. Clift, Aug 20, 2004
    #10
  11. M. Clift

    Lo?c Mah? Guest

    Hello

    You can do it with list List Comprehensions:

    BigList = ['Jean', 'Eric', 'Remy', 'Anne', 'Denis', 'Alain', 'Armel',
    'Louis']
    SmallList = ['Eric', 'Denis', 'Georges', 'Jean']

    if ( [x for x in SmallList if x in BigList] == SmallList ):
    print "They were found"
    else:
    print "They are not in list"


    [x for x in SmallList if x in BigList] evaluates to a list with common
    elements of SmallList and BigList


    Loïc
     
    Lo?c Mah?, Aug 20, 2004
    #11
  12. M. Clift

    Peter Hansen Guest

    M. Clift wrote:

    > If I wasn't happy enough already with the examples/ideas you've all shown
    > me, how about searching as previously, but where the middle name could be
    > anything. i.e. 'Rita', 'anyname','Bob'


    How about this? (may need more test cases, and then perhaps fixes):


    class Anything:
    '''wildcard: matches anything'''
    pass


    def sliceCompare(left, right):
    '''compare left and right, returning True if equal (allows wildcard)'''
    if len(left) != len(right):
    return False
    else:
    for l, r in zip(left, right):
    if Anything in [l, r]:
    pass
    elif l != r:
    return False
    else:
    return True


    def sliceIndex(seq, sub, start=0):
    '''search starting at 'start' for sub in seq, return index of match
    or -1'''
    try:
    i = seq.index(sub[0], start)
    while i >= 0:
    if sliceCompare(seq[i:i+len(sub)], sub):
    return i
    i = seq.index(sub[0], i+1)
    except ValueError:
    pass
    return -1



    def test():
    case1 = ['Rita', 'Sue', 'Bob']
    alist = 'Rita Mary Jane Bob Sue Carl Hans Rita Bob Sue'.split()
    assert sliceIndex([], case1) == -1
    assert sliceIndex(alist, case1) == -1

    alist = 'Rita Mary Jane Bob Rita Carl Bob Hans Rita Sue Bob Sue
    Rita Sue Bob'.split()
    assert sliceIndex(alist, case1) == 8
    assert sliceIndex(alist, case1, 9) == 12
    assert sliceIndex(alist, case1, 13) == -1

    case2 = ['Rita', Anything, 'Bob']
    assert sliceIndex(alist, case2) == 4
    assert sliceIndex(alist, case2, 5) == 8
    assert sliceIndex(alist, case2, 9) == 12


    if __name__ == '__main__':
    test()
     
    Peter Hansen, Aug 20, 2004
    #12
  13. M. Clift

    Peter Otten Guest

    Peter Hansen wrote:

    > M. Clift wrote:
    >
    >> If I wasn't happy enough already with the examples/ideas you've all shown
    >> me, how about searching as previously, but where the middle name could be
    >> anything. i.e. 'Rita', 'anyname','Bob'

    >
    > How about this? (may need more test cases, and then perhaps fixes):


    A properly crafted test suite invites refactoring :)

    class Anything:
    '''wildcard: matches anything'''
    def __eq__(self, other):
    return True
    Anything = Anything() # bad style, I know

    def sliceIndex(seq, sub, start=0):
    '''search starting at 'start' for sub in seq, return index of match
    or -1'''
    try:
    i = seq.index(sub[0], start)
    while i >= 0:
    if seq[i:i+len(sub)] == sub:
    return i
    i = seq.index(sub[0], i+1)
    except ValueError:
    pass
    return -1

    > def test():
    > case1 = ['Rita', 'Sue', 'Bob']
    > alist = 'Rita Mary Jane Bob Sue Carl Hans Rita Bob Sue'.split()
    > assert sliceIndex([], case1) == -1
    > assert sliceIndex(alist, case1) == -1
    >
    > alist = 'Rita Mary Jane Bob Rita Carl Bob Hans Rita Sue Bob Sue
    > Rita Sue Bob'.split()
    > assert sliceIndex(alist, case1) == 8
    > assert sliceIndex(alist, case1, 9) == 12
    > assert sliceIndex(alist, case1, 13) == -1
    >
    > case2 = ['Rita', Anything, 'Bob']
    > assert sliceIndex(alist, case2) == 4
    > assert sliceIndex(alist, case2, 5) == 8
    > assert sliceIndex(alist, case2, 9) == 12
    >
    >
    > if __name__ == '__main__':
    > test()
     
    Peter Otten, Aug 21, 2004
    #13
  14. > You can do it with list List Comprehensions:
    >
    > BigList = ['Jean', 'Eric', 'Remy', 'Anne', 'Denis', 'Alain', 'Armel',
    > 'Louis']
    > SmallList = ['Eric', 'Denis', 'Georges', 'Jean']
    >
    > if ( [x for x in SmallList if x in BigList] == SmallList ):
    > print "They were found"
    > else:
    > print "They are not in list"
    >
    >
    > [x for x in SmallList if x in BigList] evaluates to a list with common
    > elements of SmallList and BigList


    A little change:

    Difference = [x for x in SmallList if x not in BigList]
    if not Difference:
    print "They were found"
    else:
    print Difference, "were not found in the list"
     
    Shane Holloway (IEEE), Aug 23, 2004
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Cyrille Lavigne

    Re: Rita Sue and Bob too

    Cyrille Lavigne, Aug 20, 2004, in forum: Python
    Replies:
    3
    Views:
    325
    Andrew Durdin
    Aug 21, 2004
  2. Ben Last

    RE: Rita Sue and Bob too

    Ben Last, Aug 20, 2004, in forum: Python
    Replies:
    3
    Views:
    310
    Neal Holtz
    Aug 20, 2004
  3. Ben Last

    RE: Rita Sue and Bob too

    Ben Last, Aug 20, 2004, in forum: Python
    Replies:
    2
    Views:
    394
    M. Clift
    Aug 20, 2004
  4. http://clearblogs.com/rita/24759/

    http://clearblogs.com/rita/24759/

    http://clearblogs.com/rita/24759/, Jan 5, 2007, in forum: ASP .Net
    Replies:
    0
    Views:
    340
    http://clearblogs.com/rita/24759/
    Jan 5, 2007
  5. Tim Streater

    @RH - Messrs Sue, Grabbit, and Runne

    Tim Streater, Jun 21, 2010, in forum: C Programming
    Replies:
    0
    Views:
    295
    Tim Streater
    Jun 21, 2010
Loading...

Share This Page