通过将嵌套列表和另一个列表强制转换为集合来查找它们之间的公共项

Finding common items between nested list and another list by casting them to set

我有以下两个列表,我正在尝试找出它们之间的常用词。我试图从 l2 中提取单词(忽略数字)并将它们存储在 l3 中,但我不断收到错误消息:

list indices must be integers or slices, not tuples

我对修复感兴趣,或者是否有更好的解决方法。

l1=['the', 'and', 'to', 'of', 'a', 'in', 'is', 'that']
l2=[('the', 637), ('of', 252), ('a', 208), ('to', 207), ('in', 147), 
    ('and', 134), ('that', 134), ('was', 133)]


l3= list(map(lambda x: set(l2[x][x]), l2[0:6]))

print(set(l1 & l3))

您可以使用列表理解,并检查哪个元组的第一个元素包含在 l1 中。您可以通过从 l1:

构造一个 set 来降低操作的复杂性
s1 = set(l1)

l3 = [s for s,*_ in l2 if s in s1]
# ['the', 'of', 'a', 'to', 'in', 'and', 'that']

或者我们也可以使用 zip 并在第一个元素上建立索引:

set(l1).intersection(list(zip(*l2))[0])

请注意,您的方法无效,因为您正在尝试使用元组进行索引。 lambda x 每次都收到一个元组,因为您直接迭代 l2 。如果你有长度 2 个子列表,你也可以考虑使用字典,你 可以 使用给定的键访问它。鉴于您的数据结构,看起来这对您来说可能是一个不错的选择:

d = dict(l2)

[i for i in l1 if i in d]
# ['the', 'and', 'to', 'of', 'a', 'in', 'that']

使用set intersection:

s1 = set(l1)

i = s1.intersection( e[0] for e in l2 )

print(i) # set(['a', 'and', 'that', 'of', 'to', 'in', 'the'])

集合交集(方法)可以使用任何可迭代对象来找到与调用它的集合的交集。


您的错误源于不正确地使用 lambda:

map(lambda x: set(l2[x][x]), l2[0:6]))

每个 x 是 l2 的一个元素(您只取 l2 的前六个元素。map 取输入迭代的每个元素并应用您提供的函数。对于 l2 的第一个元素,这将是:

set(l2[('the', 637)][('the', 637)]) 

这显然是错误的。

您可以将列表 l1 转换为 set,然后您可以使用列表理解:

l1= ['the', 'and', 'to', 'of', 'a', 'in', 'is', 'that']
l1 = set(l1)

l2=[('the', 637), ('of', 252), ('a', 208), ('to', 207), ('in', 147), ('and', 134), ('that', 134), ('was', 133)]

l3 = [t[0] for t in l2 if t[0] in l1]

修正你自己的方法:

l3 = set(map(lambda x: x[0], l2))  # first element from each pair in l2

print(set(l1) & l3)  # must intersect set and set, not list and set