Ich versuche zu tun:
award_dict = {
"url" : "http://facebook.com",
"imageurl" : "http://farm4.static.flickr.com/3431/3939267074_feb9eb19b1_o.png",
"count" : 1,
}
def award(name, count, points, desc_string, my_size, parent) :
if my_size > count :
a = {
"name" : name,
"description" : desc_string % count,
"points" : points,
"parent_award" : parent,
}
a.update(award_dict)
return self.add_award(a, siteAlias, alias).award
Aber wenn ich mich in der Funktion wirklich umständlich gefühlt hätte und ich es lieber getan hätte:
return self.add_award({
"name" : name,
"description" : desc_string % count,
"points" : points,
"parent_award" : parent,
}.update(award_dict), siteAlias, alias).award
Warum gibt update das Objekt nicht zurück, damit Sie es verketten können?
JQuery führt dies aus, um eine Verkettung durchzuführen. Warum ist es in Python nicht akzeptabel?
python
dictionary
language-design
language-features
Paul Tarjan
quelle
quelle
newdict = dict(dict001, **dict002)
Antworten:
Python implementiert meistens eine pragmatisch gefärbte Variante der Befehl-Abfrage-Trennung : Mutatoren kehren zurück
None
(mit pragmatisch induzierten Ausnahmen wiepop
;-), sodass sie unmöglich mit Accessoren verwechselt werden können (und in diesem Sinne ist die Zuweisung kein Ausdruck, die Aussage -Expressionstrennung ist da und so weiter).Das bedeutet nicht, dass es nicht viele Möglichkeiten gibt, Dinge zusammenzuführen, wenn Sie wirklich wollen, z. B.
dict(a, **award_dict)
ein neues Diktat zu erstellen , das dem ähnelt, das Sie scheinbar zurückgeben möchten..update
Warum also nicht DAS verwenden, wenn Sie es wirklich für wichtig halten? ?Bearbeiten : Übrigens müssen Sie in Ihrem speziellen Fall auch
a
unterwegs nichts erstellen :erstellt ein einzelnes Diktat mit genau der gleichen Semantik wie Ihre
a.update(award_dict)
(einschließlich im Falle von Konflikten die Tatsache, dass Einträgeaward_dict
die von Ihnen explizit angegebenen überschreiben; um die andere Semantik zu erhalten, dh um explizite Einträge zu haben, die solche Konflikte "gewinnen", passierenaward_dict
als einziges Positions arg, vor dem Schlüsselwort eines und beraubte der**
Form -dict(award_dict, name=name
etc etc).quelle
a
insgesamt vermeidet , übrigensTypeError
dict(old_dict, old_key=new_value)
wirft nicht mehrere Werte für das Schlüsselwort und gibt ein neues Diktat zurück.Die Python-API unterscheidet konventionell zwischen Prozeduren und Funktionen. Funktionen berechnen neue Werte aus ihren Parametern (einschließlich aller Zielobjekte). Prozeduren ändern Objekte und geben nichts zurück (dh sie geben None zurück). Prozeduren haben also Nebenwirkungen, Funktionen nicht. update ist eine Prozedur, daher wird kein Wert zurückgegeben.
Die Motivation dafür ist, dass Sie sonst unerwünschte Nebenwirkungen bekommen können. Erwägen
Wenn reverse (wodurch die Liste an Ort und Stelle umgekehrt wird) auch die Liste zurückgeben würde, könnten Benutzer denken, dass reverse eine neue Liste zurückgibt, die bar zugewiesen wird, und niemals bemerken, dass foo auch geändert wird. Wenn Sie Reverse Return None ausführen, erkennen sie sofort, dass der Balken nicht das Ergebnis der Umkehrung ist, und sehen genauer nach, wie sich Reverse auswirkt.
quelle
reverse(foo)
fühlt sich komisch an.bar=foo[:]
) und setzen Sie die Kopie dann zurück.bar = foo.reverse()
könnte man denken, dassfoo
das nicht geändert wird. Um Verwirrung zu vermeiden, haben Sie beidefoo.reverse()
undbar = reversed(foo)
.Das ist so einfach wie:
quelle
Beachten Sie, dass nicht nur das zusammengeführte Diktat zurückgegeben wird, sondern auch der erste Parameter an Ort und Stelle geändert wird. Dikt_merge (a, b) ändert also a.
Oder natürlich können Sie alles inline erledigen:
quelle
lambda
sollte so nicht verwendet werden, anstatt herkömmliche Funktion verwendendef
statta.update(b) or a
nicht genug Ruf für Kommentar links oben Antwort
@beardc das scheint keine CPython-Sache zu sein. PyPy gibt mir "TypeError: Schlüsselwörter müssen Zeichenfolgen sein"
Die Lösung mit
**kwargs
funktioniert nur, weil das zusammenzuführende Wörterbuch nur Schlüssel vom Typ Zeichenfolge enthält .dh
vs.
quelle
Es ist nicht so, dass es nicht akzeptabel ist, sondern dass
dicts
es nicht so implementiert wurde.Wenn Sie sich Djangos ORM ansehen, wird die Verkettung in großem Umfang genutzt. Es ist nicht entmutigend, Sie könnten sogar erben
dict
und nur überschreibenupdate
, um Updates durchzuführen undreturn self
, wenn Sie es wirklich wollen.quelle
so nah wie möglich an Ihrer vorgeschlagenen Lösung
quelle
Für diejenigen, die zu spät zur Party kommen, hatte ich ein Timing zusammengestellt (Py 3.7), um das zu zeigen
.update()
basierte Methoden ein bisschen (~ 5%) schneller aussehen, wenn Eingaben erhalten bleiben, und merklich (~ 30%) schneller, wenn sie nur an Ort und Stelle aktualisiert werden .Wie üblich sollten alle Benchmarks mit einem Körnchen Salz genommen werden.
Die Timings für die In-Place-Operationen sind etwas kniffliger, daher müsste sie entlang einer zusätzlichen Kopieroperation geändert werden (die erste Timing dient nur als Referenz):
quelle
quelle
Ich habe es gerade selbst in Python 3.4 versucht (konnte also die ausgefallene
{**dict_1, **dict_2}
Syntax nicht verwenden).Ich wollte in der Lage sein, Schlüssel ohne Zeichenfolge in Wörterbüchern zu haben und eine beliebige Anzahl von Wörterbüchern bereitzustellen.
Außerdem wollte ich ein neues Wörterbuch
collections.ChainMap
erstellen, also habe ich mich dafür entschieden, es nicht zu verwenden (irgendwie der Grund, warum ich es anfangs nicht verwenden wolltedict.update
.Folgendes habe ich am Ende geschrieben:
quelle