Thread: Comparing Lists

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2004
    Posts
    13
    Rep Power
    0

    Comparing Lists


    I have a question I need some help with about lists.
    I have 2 lists (one being generated from a file and the other one from a database) that I need to compare against each other.

    Can some one help me:

    - compare the lists against each other
    - take the differences between the lists and append that information to a 3rd list so I can print it out

    Code:
    # generated from reading a file
    list 1 ['testName', 'test@email.com', '123 street', '/usr/local/bin/myScript.sh', 'None']
    
    # generated from a database table
    list 2 ['testName', 'test@email.com', '456 street', '/usr/local/bin/orTest9d.sh', 'None']
    
    # shows the differences between lists -- HELP!
    list 3 []
    print "differences:", list 3
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2001
    Location
    Houston, TX
    Posts
    383
    Rep Power
    14
    I suggest you use Python 2.3's sets and then just take the difference of each of the two sets (lists can be coerced into sets simply by calling Set() constructor on them)
    Debian - because life's too short for worrying.
    Best. (Python.) IRC bot. ever.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Canada
    Posts
    185
    Rep Power
    0
    why don't you check out the zip() function in your python document. the
    PHP Code:
    not 
    operator and the basic lists methods, like append. then write a function that iterates through the contents of the lists and appends to the datalist you want it to.
    "In theory, there is no difference between theory and practice.
    But, in practice, there is."

  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    If the order of the elements is not important then Strike is right, sets are what you want.

    Code:
    >>> import sets
    >>> list1 = ['testName', 'test@email.com', '123 street', '/usr/local/bin/myScript.sh', 'None']
    >>> list2 = ['testName', 'test@email.com', '456 street', '/usr/local/bin/orTest9d.sh', 'None']
    >>> 
    >>> print sets.Set(list1) ^ sets.Set(list2)
    Set(['/usr/local/bin/myScript.sh', '456 street', '/usr/local/bin/orTest9d.sh', '123 street'])
    >>> print sets.Set(list1) - sets.Set(list2)
    Set(['/usr/local/bin/myScript.sh', '123 street'])
    >>> print sets.Set(list1) | sets.Set(list2)
    Set(['456 street', '/usr/local/bin/orTest9d.sh', 'None', '/usr/local/bin/myScript.sh', 'testName', '123 street', 'test@email.com'])
    >>> print sets.Set(list1) & sets.Set(list2)
    Set(['None', 'test@email.com', 'testName'])
    >>> 
    >>> #convert a set back into a list:
    >>> set = sets.Set(list1) ^ sets.Set(list2)
    >>> list(set)
    ['/usr/local/bin/myScript.sh', '456 street', '/usr/local/bin/orTest9d.sh', '123 street']
    >>>
    Dave - The Developers' Coach
    Last edited by DevCoach; July 28th, 2004 at 03:47 AM.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    If the order is important, i.e. you only want to compare list1[0] with list2[0], then you can use a zip and compare the entries, as caroundw5h said.

    e.g. This will create a list of tuples of the non-matching entries:

    Code:
    >>> print [ (x, y) for (x, y) in zip(list1, list2) if x != y]
    [('123 street', '456 street'), ('/usr/local/bin/myScript.sh', '/usr/local/bin/orTest9d.sh')]
    >>>
    Dave - The Developers' Coach
  10. #6
  11. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Yet another way to do this, originally written for working with multiple iterators. But still, itll work prefectly in here too.

    Code:
    #!/usr/bin/env python
    
    def group(*iterators):
        while True:
            yield [iterator.next() for iterator in iterators]
            
    if __name__ == '__main__':
    
        list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        list2 = [1, 2, 3, 4, 4, 6, 7, 8, 9, 11]
        list3 = []
    
        for item1, item2 in group(iter(list1), iter(list2)):
            if item1 != item2:
                list3.append((item1, item2))
        print list3
    Pretty easy to use..

    >>> def group(*iterators):
    ... while True:
    ... yield [iterator.next() for iterator in iterators]
    ...
    >>> l1 = [1, 2, 3,4 , 5, 6, 7, 8, 9]
    >>> l2 = [2, 3, 4, 5, 6, 7, 9, 8, 9]
    >>> [(x, y) for x, y in group(iter(l1), iter(l2)) if x != y]
    [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 9)]
    >>>
    Still, i think Dave has the best sugestion, if order maters to you, use the zip() function!

    Mark.
    programming language development: www.netytan.com Hula

  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2003
    Location
    Canada
    Posts
    185
    Rep Power
    0
    Originally Posted by DevCoach
    If the order is important, i.e. you only want to compare list1[0] with list2[0], then you can use a zip and compare the entries, as caroundw5h said.

    e.g. This will create a list of tuples of the non-matching entries:

    Code:
    >>> print [ (x, y) for (x, y) in zip(list1, list2) if x != y]
    [('123 street', '456 street'), ('/usr/local/bin/myScript.sh', '/usr/local/bin/orTest9d.sh')]
    >>>
    Dave - The Developers' Coach
    Nice list comprehension. I didn't even think of that. Very pythonic.
    "In theory, there is no difference between theory and practice.
    But, in practice, there is."

  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Feb 2004
    Location
    London, England
    Posts
    1,585
    Rep Power
    1373
    Originally Posted by netytan
    Code:
    #!/usr/bin/env python
    
    def group(*iterators):
        while True:
            yield [iterator.next() for iterator in iterators]

    This functionality is already built into the standard library, as itertools.izip. From the docs:

    izip( *iterables)

    Make an iterator that aggregates elements from each of the iterables. Like zip() except that it returns an iterator instead of a list. Used for lock-step iteration over several iterables at a time. Equivalent to:

    Code:
         def izip(*iterables):
             iterables = map(iter, iterables)
             while iterables:
                 result = [i.next() for i in iterables]
                 yield tuple(result)
    Changed in version 2.3.1: When no iterables are specified, returns a zero length iterator instead of raising a TypeError exception.
    Of course there are imap and ifilter functions as well. The itertool functions are all written in C, so should be much faster than the Python equivalents.

    If you do any functional programming with lists, generators etc, then it is well worth while getting to know the itertools module, since there are a lot of interesting goodies in there.

    Dave - The Developers' Coach
  16. #9
  17. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Thanks Dave, i never once thought about the itertools module when i wrote it . And then once i had it i didnt bother looking for an alternative .

    Mark.
    programming language development: www.netytan.com Hula


IMN logo majestic logo threadwatch logo seochat tools logo