在键为元组的字典中,删除在特定位置没有特定值的所有键

时间:2020-10-08 15:00:53

标签: python tuples

我有一本字典,其中每个键都是元组N。每个位置都有一个字符串或一个空字符串。

d = {('Word A','Word B','','','Word C',....) : 50,
     ('Word F', '','','',....,'Word H') : 10, 
     ....
     }

我有一个包含索引的类别字典,如果d中的键在索引指定的每个位置都有一个空字符串,则它属于该类别。键可以属于多个类别。

category_dictionary= { 'Category A':[1,2,3] , 'Category B' : [0,3,4] , .... }

在此示例中,d ('Word F', '','','',....,'Word H')中的第二个条目属于Category A,因为它在位置1,2和3处具有空字符串。

我要删除d中所有不属于任何类别的键。什么是有效的方法?这是可以正常运行但运行缓慢的代码。

    filtered_list = []
    for current_tuple in list(d.keys()):
        keep_tuple = False
        for category,idxs in category_dictionary.items():
            all_idxs_empty = True
            for idx in idxs:
                if current_tuple[idx] != '':
                    all_idxs_empty = False
            if all_idxs_empty:
                filtered_list.append(current_tuple)
                break

     d_filter = {k:v for k,v in d.items() if k in filtered_list}

什么是更有效的方法?如果我有M个键,T个类别并且最大长度为U,则复杂度介于复杂度[O(M*T),O(M*T*U)]

之间

有办法以某种方式降低复杂性吗?

N = 3和2个类别的示例数据

d = {('A','','B','H') : 10, 
     ('','','','H') : 20,
     ('','','F','T') : 30,
     ('A','C','G','') : 0
     }

category_dictionary = { 'Category A':[0,1],'Category B' :[3]}

预期输出

d_filter = {('','','','H'): 20,
           ('','','F','T'):30,
           ('A','C','G','') : 0
           }

2 个答案:

答案 0 :(得分:1)

尝试一下:

def f(tuple_, category_dictionary):
    l=[i for i in range(len(tuple_)) if tuple_[i]=='']
    return any([set(k)-set(l)==set() for k in category_dictionary.values()])

m=list(d.keys())    
for i in m:
    if not f(i, category_dictionary):
        del d[i]

答案 1 :(得分:0)

不确定这是否更快,但这更简单。

filtered_list = []
category_set = [set(x) for x in category_dictionary.values()]

for current_tuple in list(d.keys()):
    #in_category = [i for i,x in enumerate(current_tuple) if x=='']  in category_dictionary.values()
    current_set = {i for i,x in enumerate(current_tuple) if x==''}
    in_category = any([set.issubset(x, current_set) for x in category_set])
    if in_category:
        filtered_list.append(current_tuple)

d_filter = {k:v for k,v in d.items() if k in filtered_list}
d_filter