user1985351
user1985351

Reputation: 4689

Comparing Multiple Lists Python

I'm trying to compare multiple lists. However the lists aren't label...normally. I'm using a while loop to make a new list each time and label them accordingly. So for example, if the while loop runs 3 times it will make a List1 a List2 and List3. Here is then snippet of the code to create the list.

for link in links:
    print('*', link.text)
    locals()['list{}'.format(str(i))].append(link.text)

So I want to compare each list for the strings that are in them but I want to compare all the lists at once then print out the common strings.

I feel like I'll be using something like this, but I'm not 100% sure.

lists = [list1, list2, list3, list4, list5, list6, list7, list8, list9, list10]
common = list(set().union(*lists).intersection(Keyword))

Upvotes: 0

Views: 18917

Answers (2)

Jon Gauthier
Jon Gauthier

Reputation: 25572

Rather than directly modifying locals() (generally not a good idea), use a defaultdict as a container. This data structure allows you to create new key-value pairs on the fly rather than relying on a method which is sure to lead to a NameError at some point.

from collections import defaultdict

i = ...

link_lists = defaultdict(list)
for link in links:
    print('*', link.text)
    link_lists[i].append(link.text)

To find the intersection of all of the lists:

all_lists = list(link_lists.values())
common_links = set(all_lists[0]).intersection(*all_lists[1:])

In Python 2.6+, you can pass multiple iterables to set.intersection. This is what the star-args do here.


Here's an example of how the intersection will work:

>>> from collections import defaultdict
>>> c = defaultdict(list)
>>> c[9].append("a")
>>> c[0].append("b")
>>> all = list(c.values())
>>> set(all[0]).intersection(*all[1:])
set()
>>> c[0].append("a")
>>> all = list(c.values())
>>> set(all[0]).intersection(*all[1:])
{'a'}

Upvotes: 3

Juan Carlos Moreno
Juan Carlos Moreno

Reputation: 2784

You have several options,

option a)

use itertools to get a cartesian product, this is quite nice because its an iterator

a = ["A", "B", "C"]
b = ["A","C"]
c = ["C","D","E"]

for aval,bval,cval in itertools.product(a,b,c):
    if aval == bval and bval == cval:
        print aval

option b)

Use sets (recommended):

 all_lists = []
 # insert your while loop X times
 for lst in lists:         # This is my guess of your loop running.
     currentList = map(lambda x: x.link, links)
     all_lists.append(currentList) # O(1) operation

 result_set = set()
 if len(all_lists)>1:
      result_set = set(all_lists[0]).intersection(*all_lists[1:]) 
 else:
      result_set = set(all_lists[0])

Using the sets, however, will be faster

Upvotes: 2

Related Questions