检查两个列表的交集

时间:2017-12-13 08:45:42

标签: python

我将关键字分类为以下嵌套列表,

Keywords_33=[('File_2', ['with', 'as']),
             ('Module_2', ['from', 'import']),
             ('Constant_3', {'bool': ['False', 'True'],
                             'none': ['None']}),
             ('Operator_4', {'boolean_operation': {'or', 'and', 'not'},
                             'comparison': {'is'}}),
             ('Container_operation_2', ['in', 'del']),
             ('Klass_1', ['class']),
             ('Function_7',['lambda', 'def', 'pass',
                            'global', 'nonlocal',
                            'return', 'yield']),
             ('Repetition_4', ['while', 'for', 'continue', 'break']),
             ('Condition_3', ['if', 'elif', 'else']),
             ('Debug_2', ['assert', 'raise']),
             ('Exception_3', ['try', 'except', 'finally'])]

我打算按类别确认每个关键字而不留下任何关键字。 我考虑的最方便的是首先将Keywords_33转换为字符串。

from keyword import kwlist
In [55]: print(kwlist)
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
In [54]: from keyword import kwlist
...: s = str(Keywords_33)
...: [keyword for keyword in kwlist if keyword not in s]
...:
Out[54]: []
# It indicate no keyword left

如何优雅地完成这项任务?

2 个答案:

答案 0 :(得分:3)

依赖于嵌套的dicts / list列表的字符串表示有点危险,因为你可以匹配你不想要的单词/子串(例如elif包含if所以如果你的列表包含elif,它也会匹配if。一些聪明的re.findall可以工作,在引号之间提取文字,但这仍然是一个黑客。

相反,你可以创建一个dicts或列表值(取决于类型)的列表,它会产生:

['with', 'as', 'from', 'import', ['None'], ['False', 'True'], {'and', 'or', 'not'}, {'is'}, 'in', 'del', 'class', 'lambda', 'def', 'pass', 'global', 'nonlocal', 'return', 'yield', 'while', 'for', 'continue', 'break', 'if', 'elif', 'else', 'assert', 'raise', 'try', 'except', 'finally']

然后在不规则的项目列表(Flatten (an irregular) list of lists)上使用拼合食谱,转换为set并减去两种方式/相交:

Keywords_33=[('File_2', ['with', 'as']),
             ('Module_2', ['from', 'import']),
             ('Constant_3', {'bool': ['False', 'True'],
                             'none': ['None']}),
             ('Operator_4', {'boolean_operation': {'or', 'and', 'not'},
                             'comparison': {'is'}}),
             ('Container_operation_2', ['in', 'del']),
             ('Klass_1', ['class']),
             ('Function_7',['lambda', 'def', 'pass',
                            'global', 'nonlocal',
                            'return', 'yield']),
             ('Repetition_4', ['while', 'for', 'continue', 'break']),
             ('Condition_3', ['if', 'elif', 'else']),
             ('Debug_2', ['assert', 'raise']),
             ('Exception_3', ['try', 'except', 'finally'])]

import collections
from keyword import kwlist

def flatten(l):
    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
            yield from flatten(el)
        else:
            yield el

my_keywords = set(flatten(x for _,l in Keywords_33 for x in (l if isinstance(l,list) else l.values())))

在这种情况下set(kwlist) == my_keywords

答案 1 :(得分:0)

string pattern = @"\b" + searchText + @"\b"

我区分,如果第二个元素是列表或字典。 (注意,在这种情况下它可以工作,因为每个元组都包含两个元素)。在列表的情况下,我可以轻松地迭代并比较元素是否在kwlist中。在字典的情况下,我可以遍历字典的值并进行比较,如果值在kwlist中