0

我正在尝试比较多个列表。但是列表不是标签......通常。我每次都使用一个while循环来创建一个新列表并相应地标记它们。因此,例如,如果 while 循环运行 3 次,它将生成List1aList2List3。这是创建列表的代码片段。

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

所以我想比较每个列表中的字符串,但我想一次比较所有列表,然后打印出公共字符串。

我觉得我会使用这样的东西,但我不是 100% 确定。

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

2 回答 2

3

而不是直接修改locals()(通常不是一个好主意),使用 adefaultdict作为容器。这种数据结构允许您动态创建新的键值对,而不是依赖于NameError在某个时候肯定会导致 a 的方法。

from collections import defaultdict

i = ...

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

查找所有列表的交集

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

在 Python 2.6+ 中,您可以将多个迭代传递给set.intersection. 这就是star-args 在这里所做的。


以下是交叉口如何工作的示例:

>>> 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'}
于 2013-04-05T02:52:47.020 回答
1

你有几个选择,

选项 a)

使用 itertools 获得笛卡尔积,这非常好,因为它是一个迭代器

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

选项 b)

使用集合(推荐)

 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])

但是,使用套装会更快

于 2013-04-05T02:50:21.253 回答