[Zope] Finding matches between two lists

Jim Washington jwashin@vt.edu
Fri, 03 Mar 2000 12:34:51 -0500


Hi, ed.

I think I am a bit dense today, so could not quite understand completely
what you are doing, but

If you want to find matches between lists, there is a cool thing in
Python that can possibly help you.  

Let's say I have two lists, list1 and list2, and I want to know what in
list1 is in list2, which is I think what you are going for.

list1 = ['n', 'b', 'r']
list2 = ['f', 'd', 'b']

def intersect(lista, listb):

    tmp = []
    for anitem in lista:       #iterate through lista
        if (anitem in listb):  #check to see if the item is in listb. 
This is the cool thing.
            tmp.append(anitem) #if there, append to the temp list
    return tmp                 #return the temp list

print intersect(list1, list2)  #should be ['b']

If I want no dupes, (if 'b' is in list1 twice, it will be returned
twice) I probably would use a dictionary instead of a list and return
the keys, e.g, 

def intersectnodupes(lista, listb):
    tmp = {}
    for anitem in lista:       #iterate through lista
        if (anitem in listb):  #check to see if the item is in listb. 
This is the cool thing.
            tmp[anitem] = 1    #if there, throw it into the doct
    tmp1 = tmp.keys()          #get the keys (arbitrary order, alas!)
    tmp1.sort()                #the keys are in arbitrary order no
longer
    return tmp1                #return the unduplicated list

In DTML, you can use the 'if athing in alist' thing too:

<dtml-call "REQUEST.set('list1', ['n', 'b', 'r'])"> <!-- or use your own
lists -->
<dtml-call "REQUEST.set('list2', ['f', 'd', 'b'])">

<dtml-in list1>
<dtml-if "_['sequence-item'] in list2">
<dtml-var sequence-item> <!-- do something with the things in list1 that
are in list2 --> 
</dtml-if>
</dtml-in>

Regards,

-- Jim Washington

ed colmar wrote:
> 
> Hey all!
> 
>         This question went by last month without a reply, so I am going to try it
> again.  I've also gotten a bit closer to the answer on my own.
> 
>         ---------
> 
>         The layout:
> 
>         Most of my code is in a Python Product, but there is still a bunch of dtml
> used.
> 
>         I have a class called "person" with a string variable called "name",  and
> a class called "event" with a list variable called "eventnames".
> 
>         Now when a addEventForm is filled out, then the viewEventPage is called, I
> want all the people listed in "eventnames" to have a link to thier home
> page if they exist.
> 
>         ---------
> 
>         The DTML attempt:
> 
>         I could never get this to work correctly.  Becuase it is looking through
> two lists, the code causes the "eventnames" to be dispayed once for each
> person listed.
> 
>         <dtml-if eventnames><BR><BR><STRONG>Featuring people :</STRONG>
>         <dtml-with "PARENTS[0]">
>           <dtml-in personValues>
>             <dtml-if "meta_type == 'SRPersonPost'">
>               <dtml-in eventnames>
>                  <dtml-if "_['sequence-item'] == name">
>                    <A href="<dtml-var site_url>/<dtml-var id>"><dtml-var
> sequence-item></a>,
>                  <dtml-else><dtml-var sequence-item>,
>                  </dtml-if>
>               </dtml-in>
>             </dtml-if>
>           </dtml-in>
>         </dtml-with>
>     </dtml-if eventnames>
> 
>         ---------
> 
>         The Python attempt:
> 
>         So I tried to change my strategy, and build a method to find the matches,
> and return the list with the ids (if the person is listed) or a 'None' if
> they are not listed.  I haven't been able to figure out what is going wrong
> with this.
> 
>     def list_dj_list(self, namelist):
>         """ should return a list of names & IDs from a list of names
>         """
>         rlist = map(None,self.ids)
>         rlist = filter(lambda x,p=self : p.data[x].validated, rlist)
>         rlist = filter(lambda x,p=self : p.data[x].meta_type ==
> 'SRPersonPost', rlist)
>         rlist = filter(lambda x,p=self : p.data[x].name, rlist)
>         rnames = []
>         for i in range(len(namelist)):
>             rnamelist = rlist
>             rname = filter(lambda x,p=self,s=namelist[i] : p.data[x].name
> == s, rnamelist)
>             if len(rnames) == 0:
>                 rnames.append('None')
>             elif len(rnames) == 1:
>                 rnames.append(rname)
>             else:
>                 rnames.append('multiples')
> 
>         return rnames
> 
>         ---------
> 
>         The question:
> 
>         How can this be achieved?  I don't have a preferance over dtml or python,
> but it seems like a python method is the proper way to do it.
> 
>         Thanks for any help!
> 
>         -ed-