Ik moet een functie schrijven add_to_dict(d, key_value_pairs)
die elk gegeven sleutel/waarde-paar toevoegt aan een python-woordenboek. Het argument key_value_pairs
is een lijst met tuples in de vorm (key, value)
.
De functie zou een lijst moeten retourneren van alle sleutel/waarde-paren die zijn gewijzigd (met hun oorspronkelijke waarden).
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
Ik krijg steeds een foutmelding
ValueError: niet genoeg waarden om uit te pakken (verwacht 2, kreeg 1)
Hoe los ik deze fout op?
Antwoord 1, autoriteit 100%
Hoe u uw code moet debuggen
'''
@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
Blijf het resterende deel lezen als u wilt weten hoe u een dict
-object op de juiste manier kunt doorkruisen.
Verschillende manieren om een dict
object te doorkruisen
Python 3.x
De volgende segmenten laten zien hoe je een dict
in Python 3.xdoorkruist.
Herhaal de set sleutels
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)
Herhaal de set sleutel-waarde-paren
for key, value in d.items():
print(key, value)
Herhaal de reeks waarden
for value in d.values():
print(value)
Python 2.x
De volgende segmenten laten zien hoe je een dict
in Python 2.xdoorkruist.
Herhaal de set sleutels
for key in d:
value = d[key]
print(key, value)
keys()
retourneert een lijstvan de sleutelset van het woordenboek d
for key in d.keys():
value = d[key]
print(key, value)
iterkeys()
retourneert een iteratorvan de sleutelset van woordenboek d
for key in d.iterkeys():
value = d[key]
print(key, value)
Herhaal de set sleutel-waarde-paren
values()
retourneert een lijstvan de set sleutel-waarde-paar van woordenboek d
for key, value in d.items():
print(key, value)
itervalues()
retourneert een iteratorvan de set sleutel-waarde-paar van woordenboek d
for key, value in d.iteritems():
print(key, value)
Herhaal de reeks waarden
values()
retourneert een lijst van de waardenset van woordenboek d
for value in d.values():
print(value)
itervalues()
retourneert een iterator van de waardenset van woordenboek d
for value in d.itervalues():
print(value)
Referentie:
Antwoord 2, autoriteit 53%
gebruik items()
om op te lossen, zoals:
d = {"foo": "bar"}
for key, value in d.items():
print key, value
Antwoord 3, autoriteit 5%
Je kunt deze fout vermijden als je het dictaat (van 1 miljoen inzendingen) niet herhaalt, maar alleen de lijst met mogelijkewijzigingen en kijkt of het iets in het dictaat verandert:
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
Uitvoer:
[] # 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
Je zou ook wat validatie in je parameters kunnen gooien – als een parameter fout is, wordt er niets uitgevoerd en ontstaat er een spreekfout:
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
Dus je krijgt duidelijkere foutmeldingen:
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