编写一个函数add_to_dict(d, key_value_pairs)
,将每个给定的键/值对添加到给定的字典中。参数key_value_pairs
将是格式为(key, value)
的元组列表。
该函数应返回所有已更改的键/值对的列表(及其原始值)。
def add_to_dict(d, key_value_pairs):
newlist = []
for key,value in d:
for x,y in key_value_pairs:
if x == key:
newlist.append(x,y)
return newlist
我一直遇到错误
ValueError:没有足够的值可解包(预期2,得到1)
我该如何完成这个问题?
答案 0 :(得分:5)
使用items()
进行解决,例如:
d = {"foo": "bar"}
for key, value in d.items():
print key, value
答案 1 :(得分:5)
'''
@param d: a dictionary
@param key_value_pairs: a list of tuples in the form `(key, value)`
@return: a list of tuples of key-value-pair updated in the original dictionary
'''
def add_to_dict(d, key_value_pairs):
newlist = []
for pair in key_value_pairs:
# As is mentioned by Mr Patrick
# you might not want to unpack the key-value-pair instantly
# to avoid possible corrupted data input from
# argument `key_value_pairs`
# if you can't guarantee its integrity
try:
x, y = pair
except (ValueError):
# unable to unpack tuple
tuple_length = len(pair)
raise RuntimeError('''Invalid argument `key_value_pairs`!
Corrupted key-value-pair has ({}) length!'''.format(tuple_length))
# Instead of using nesting loop
# using API would be much more preferable
v = d.get(x)
# Check if the key is already in the dictionary `d`
if v:
# You probably mean to append a tuple
# as `array.append(x)` takes only one argument
# @see: https://docs.python.org/3.7/library/array.html#array.array.append
#
# Besides, hereby I quote
# "The function should return a list of all of the key/value pairs which have changed (with their original values)."
# Thus instead of using the following line:
#
# newlist.append((x, y,))
#
# You might want a tuple of (key, old_value, new_value)
# Hence:
newlist.append((x, v, y,))
# I don't know if you want to update the key-value-pair in the dictionary `d`
# take out the following line if you don't want it
d[x] = y
return newlist
如果您想知道如何正确遍历dict
对象,请继续阅读其余部分。
dict
对象的不同方式以下部分演示了如何在 Python 3.x 中遍历dict
。
for key in d:
value = d[key]
print(key, value)
the code segment above has the same effect as the following one:
for key in d.keys():
value = d[key]
print(key, value)
for key, value in d.items():
print(key, value)
for value in d.values():
print(value)
以下部分演示了如何在 Python 2.x 中遍历dict
。
for key in d:
value = d[key]
print(key, value)
keys()
返回字典d
for key in d.keys():
value = d[key]
print(key, value)
iterkeys()
返回字典d
for key in d.iterkeys():
value = d[key]
print(key, value)
values()
返回字典d
for key, value in d.items():
print(key, value)
itervalues()
返回字典d
for key, value in d.iteritems():
print(key, value)
values()
返回字典d
的值集的列表
for value in d.values():
print(value)
itervalues()
返回字典d
的值集的迭代器
for value in d.itervalues():
print(value)
参考:
答案 2 :(得分:1)
如果您不遍历dict(一百万个条目),而仅遍历可能更改列表,并查看它是否更改了dict,则可以避免此错误:
def add_to_dict(d, key_value_pairs):
"""Adds all tuples from key_value_pairs as key:value to dict d,
returns list of tuples of keys that got changed as (key, old value)"""
newlist = []
for item in key_value_pairs:
# this handles your possible unpacking errors
# if your list contains bad data
try:
key, value = item
except (TypeError,ValueError):
print("Unable to unpack {} into key,value".format(item))
# create entry into dict if needed, else gets existing
entry = d.setdefault(key,value)
# if we created it or it is unchanged this won't execute
if entry != value:
# add to list
newlist.append( (key, entry) )
# change value
d[key] = value
return newlist
d = {}
print(add_to_dict(d, ( (1,4), (2,5) ) )) # ok, no change
print(add_to_dict(d, ( (1,4), (2,5), 3 ) )) # not ok, no changes
print(add_to_dict(d, ( (1,7), (2,5), 3 ) )) # not ok, 1 change
输出:
[] # ok
Unable to unpack 3 into key,value
[] # not ok, no change
Unable to unpack 3 into key,value
[(1, 4)] # not ok, 1 change
您还可以对参数进行一些验证-如果任何参数错误,将不执行任何操作,并且会出现语音错误:
import collections
def add_to_dict(d, key_value_pairs):
"""Adds all tuples from key_value_pairs as key:value to dict d,
returns list of tuples of keys that got changed as (key, old value)"""
if not isinstance(d,dict):
raise ValueError("The dictionary input to add_to_dict(dictionary,list of tuples)) is no dict")
if not isinstance(key_value_pairs,collections.Iterable):
raise ValueError("The list of tuples input to add_to_dict(dictionary,list of tuples)) is no list")
if len(key_value_pairs) > 0:
if any(not isinstance(k,tuple) for k in key_value_pairs):
raise ValueError("The list of tuples includes 'non tuple' inputs")
if any(len(k) != 2 for k in key_value_pairs):
raise ValueError("The list of tuples includes 'tuple' != 2 elements")
newlist = []
for item in key_value_pairs:
key, value = item
# create entry into dict if needed, else gets existing
entry = d.setdefault(key,value)
# if we created it or it is unchanged this won't execute
if entry != value:
# add to list
newlist.append( (key, entry) )
# change value
d[key] = value
return newlist
这样您会获得更清晰的错误消息:
add_to_dict({},"tata")
# The list of tuples input to add_to_dict(dictionary,list of tuples)) is no list
add_to_dict({},["tata"])
# The list of tuples includes 'non tuple' inputs
add_to_dict({},[ (1,2,3) ])
# The list of tuples includes 'tuple' != 2 elements
add_to_dict({},[ (1,2) ])
# ok