简体   繁体   English

检查两个列表的交集

[英]Check intersection of two lists

I categorized keywords as following nest list, 我将关键字归类为以下嵌套列表,

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

I intent to confirm every keyword in place by category without any left. 我打算按类别确认每个关键字是否正确。 The most convenient I consider is to convert Keywords_33 to string firstly. 我认为最方便的方法是首先将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

How to accomplish such a task elegantly? 如何优雅地完成这样的任务?

Relying on the string representation of your nested list of dicts/list is a bit hazardous because you could match words/substrings you don't want (example elif contains if so if your list contains elif , it will match if as well. Some clever re.findall could work, extracting text between quotes, but that's still a hack. 依靠字典/列表的嵌套列表的字符串表示形式有点危险,因为您可以匹配不需要的单词/子字符串(示例elif包含if ,如果您的列表包含elif ,那么它也会匹配ifre.findall可以工作,在引号之间提取文本,但这仍然是一个技巧。

Instead, you could create a list of the values of the dicts or the lists (depending on the type) which yields: 相反,您可以创建一个dict值列表或列表(取决于类型),从而产生:

['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']

then use a flatten recipe on an irregular list of items ( Flatten (an irregular) list of lists ), convert to set and substract both ways / intersect whatever: 然后在不规则的项目列表(列表的平坦化(不规则)列表 )上使用展平配方,转换为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())))

in that case set(kwlist) == my_keywords 在那种情况下set(kwlist) == my_keywords

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

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

if __name__ == '__main__':
    result = []
    for kw in kwlist:
        for key in Keywords_33:
            if isinstance(key[1], list):
                for i in key[1]:
                    if kw == i:
                        result.append(i)
            elif isinstance(key[1], dict):
                for value in key[1].values():
                    for j in value:
                        if kw == j:
                            result.append(j)

    print(result)

i distinguish, if the second element is a list or a dictionary. 我区分,如果第二个元素是列表或字典。 (Attention, in this case it works, because every tuple contains exactly two elements). (注意,在这种情况下,它起作用了,因为每个元组恰好包含两个元素)。 In the list case, i can easily iterate through and compare if the element is in the kwlist. 在列表的情况下,如果元素在kwlist中,我可以轻松地进行迭代并进行比较。 In case of dictionary, i can iterate through the values of the dictionary and compare, if the value is in kwlist 对于字典,如果值在kwlist中,我可以遍历字典的值并进行比较

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM