我想创建一个函数,它将列表作为参数,另外两个输出代表输入字典的键值。
>>> where_clause_case_1({'a': [1, 2], 'b': [1, 2], 'c':[3, 2]}, 'b', 'c')
{'a': [2], 'b': [2], 'c': [2]}
该函数应该做的是如果键值b1等于索引处的键值b2,则该函数返回整个字典,其中每个值都在该特定索引处,因此它保持不变。但是如果b1在索引处不等于b2,则该函数会从所有列表中删除该索引。我得到一个错误说“builtins.KeyError:'c'”这个具体的例子,我不明白为什么。
def dictionary_change(my_dict, b1, b2):
i = 0
for key in my_dict:
if(my_dict[b1][i] == my_dict[b2][i]):
my_dict[key][i] = my_dict[key][i]
else:
my_dict[key][i] = []
i += 1
return my_dict
答案 0 :(得分:1)
循环遍历字典键,同时增加i
。这意味着对于3个键,i
从0到2循环,但每个值中只有2个项(0和1)。这会导致索引错误。
相反,使用zip()
循环遍历两个列表,记录要保留的索引,然后将其应用于整个字典中的所有值:
def where_clause_case_1(my_dict, b1, b2):
# build a set of indices to keep
keep = {i for i, (x, y) in enumerate(zip(my_dict[b1], my_dict[b2])) if x == y}
# build a new dictionary with kept indices
return {key: [v for i, v in enumerate(value) if i in keep] for key, value in my_dict.items()}
最后一行使用字典理解({key_expression: value_expression for variables in sequence}
)构建一个新字典;基本上是一个为字典构建键和值的循环。它接受来自my_dict
的键,但改变了值。每个值都是使用列表推导构建的;另一个循环。在这里,当索引位于集keep
中时,我们将所有原始值仅。
没有理解,它看起来像这样:
def where_clause_case_1(my_dict, b1, b2):
# build a set of indices to keep
keep = set()
for i, (x, y) in enumerate(zip(my_dict[b1], my_dict[b2])):
if x == y:
keep.add(i)
# build a new dictionary with kept indices
retval = {}
for key, oldvalue in my_dict.items():
retval[key] = newvalue = []
for i, v in enumerate(oldvalue):
if i in keep:
newvalue.append(v)
return retval
演示:
>>> def where_clause_case_1(my_dict, b1, b2):
... # build a set of indices to keep
... keep = {i for i, (x, y) in enumerate(zip(my_dict[b1], my_dict[b2])) if x == y}
... # build a new dictionary with kept indices
... return {key: [v for i, v in enumerate(value) if i in keep] for key, value in my_dict.items()}
...
>>> where_clause_case_1({'a': [1, 2], 'b': [1, 2], 'c':[3, 2]}, 'b', 'c')
{'a': [2], 'c': [2], 'b': [2]}
>>> where_clause_case_1({'a': [1, 2], 'b': [1, 2], 'c':[3, 2]}, 'a', 'b')
{'a': [1, 2], 'c': [3, 2], 'b': [1, 2]}