Pythonschlange: tief, hinzufügend zum Wörterbuch? - in einem einzelnen Ausdruck
Wie erhalten I, in einem einzelnen Ausdruck, ein Wörterbuch, in dem ein Schlüsselwert Paar einem Unterwörterbuch in irgendeinem Inputwörterbuch hinzugefügt worden ist? Das Inputwörterbuch sollte unverändert gelassen werden. Es kann angenommen werden, dass das Unterwörterbuch existiert und dass das neue Schlüsselwert Paar nicht bereits im Unterwörterbuch ist.
Aktualisierung 2 (sehen Sie unten für Definition „von SOsurvivalConditions“, von etc.):
Die kürzeste Weise ist:
(SOsurvivalConditions['firstCondition'].setdefault('synonym', 'A modern form of RTFM is: Google It.'), SOsurvivalConditions)[-1]
Aktualisierung 1:
Dieses erfüllt die gegebenen Bedingungen und hat nicht die Nebenwirkung der Abänderung des Inputwörterbuches:
dict((k,dict(v, synonym='A modern form of RTFM is: Google It.') if k == "firstCondition" else v) for k,v in SOsurvivalConditions.iteritems())
Jedoch kann die kürzere (aber nur Aussage) Weise mit einer Helferfunktion angepasst werden, z.B.:
import copy
def dictDeepAdd(inputDict, dictKey, newKey, newValue):
"""
Adds new key-value pair to a sub-dictionary and
returns a new version of inputDict.
dictKey is the key in inputDict for which a new
key-value pair is added.
Side-effect: none (does not change inputDict).
"""
toReturn = copy.deepcopy(inputDict)
toReturn[dictKey][newKey] = newValue
return toReturn
dictDeepAdd(
SOsurvivalConditions,
'firstCondition',
'synonym',
'A modern form of RTFM is: Google It.'
)
Das Beispiel:
goodStyle = \
{
'answer': 'RTFM responses are not acceptable on StackOverflow - Joel Spolsky has repeatly said so in the StackOverflow podcasts.',
'RTFM' : 'RTFM is, in the less offensive version, an abbrevation for Read The Fine Manual.',
}
SOsurvivalConditions = \
{
'moodImperative' : 'be happy',
'firstCondition' : goodStyle,
}
„firstCondition“ in SOsurvivalConditions hat jetzt 2 Schlüsselwert Paare. Ein neues Schlüsselwert Paar, („Synonym“, „eine moderne Form von RTFM ist: Google It."), Bedarf hinzugefügt zu werden und das Ergebnis sollten in einem einzelnen Ausdruck verfügbar sein.
Dieses arbeitet (eine Linie, aber hier gebrochen in mehrere):
{
'moodImperative': SOsurvivalConditions['moodImperative'],
'firstCondition' :
dict(
SOsurvivalConditions['firstCondition'],
synonym = 'A modern form of RTFM is: Google It.'
)
}
und Rückkehr:
{„moodImperative“: „seien Sie“, „firstCondition“ glücklich: {„Antwort“: „RTFM-Antworten sind nicht auf StackOverflow annehmbar - Joel Spolsky hat repeatly so in den StackOverflow-Podcasts gesagt. “, „RTFM“: „RTFM ist, in der weniger offensiven Version, ein abbrevation für las das feine Handbuch. “, „Synonym“: „Eine moderne Form von RTFM ist: Google es. “}}
Jedoch es gibt viel Redundanz in diesem Ausdruck - alle Schlüssel werden wiederholt. Und „firstCondition“ erscheint zweimal. Gibt es eine elegantere Weise?
(Die Namen und der Inhalt der datastructures hier wird gebildet, aber ein wirkliches Problem darstellt, das ich heute antraf. Pythonschlangenversion: 2.6.2.).
SOsurvivalConditions['firstCondition']['synonym'] = 'A modern form of RTFM is: Google It.'
Suchen Sie nach dict.update (Dokumentation hier)?
SOsurvivalConditions['firstCondition'].update({'synonym': 'A modern form of RTFM is: Google It.'})
ist was, ich denken, Sie wünschen.
Ist hier ein, das Ihre eigenartigen Spezifikt. trifft (innerhalb zur Mehrdeutigkeit, mit der Sie sie) spezifiziert haben:
(SOsurvivalConditions['firstCondition'].setdefault('synonym', 'A modern form of RTFM is: Google It.'), SOsurvivalConditions)[-1]
Dieses ändert die Anfangsdatenstrukturen (eher als, Neue schaffend, wie die Antwort der @truppos tut) und ist auch ein Ausdruck, der das Gesamtwörterbuch zurückbringt (eher als seiend eine Aussage, wie die Antwort der @Evans oder das Zurückbringen keine, wie der @Seths).
Selbstverständlich sind viele Varianten möglich (wenn Sie den neuen Eintritt bestehendes mit dem gleichen Schlüssel„Synonym“ aufheben wünschen, eher als lassen irgend solchen vorhandenen Eintritt allein, Sie könnte __setitem anstelle des setdefault benutzen, zum Beispiel -- es ist hart, zu schätzen, was Sie in solchen Eckfällen geschehen wünschen, da Ihre Anfangsspezifikt. so hoffnungslos vieldeutig sind und es gibt keinen Zusammenhang „des wirklichen Anwendungsfalls“, der gegeben wird, um zu helfen, sie zu disambiguieren).
Redigieren Sie: wenn der Anwendungsfall jetzt in den Kommentaren erklärt ist (kein Ändern der ursprünglichen Datenstrukturen, und ein Ausdruck ist tatsächlich erforderlich, aber der Helferfunktion würde OKAY sein), ist hier, was ich vorschlagen würde:
def addSubEntry(mainDict, outerKey, innerKey, innerValue):
# copy inner and outer dicts to avoid altering initial data
result = dict(mainDict)
inner = dict(result.get(outerKey, {}))
inner[innerKey] = innerValue
result[outerKey] = inner
return result
und als der gewünschte Ausdruck, Gebrauch:
addSubEntry(SOsurvivalConditions, 'firstCondition', 'synonym', 'A modern form of RTFM is: Google It.')
Einige Varianten sind abhängig von dem genauen Verhalten möglich, das in den Eckfällen gewünscht wird. Diese Version addiert ein neues Wörterbuch (mit gerade den gegebenen inneren Schlüsselwert Paaren) wenn es vorher keinen Eintritt mit dem gegebenen Äußerschlüssel gab; wenn es solch einen vorhergehenden Eintritt gab, versucht er, ihn in ein dict zu machen (selbst wenn es sagen wir eine Liste von Schlüsselwert Tuples war) und hebt eine Ausnahme an, wenn der gerade unausführbar ist. Eine strengere Version (verlangend, dass der innere Eintritt bereits ein dict oder ein dict ähnlicher Gegenstand existierte und war und stattdessen Ausnahme anhob), verwendete möglicherweise stattdessen
inner = result[outerKey].copy()
als die zweite Aussage im Körper.
Dieses arbeitet, aber seine nicht hübschen und ich denken, dass Sie vermutlich zu weit mit Ihrem Lambda/oneliner/gehen, was auch immer Sie versuchen, zu tun:)
dict((k,dict(v, synonym='A modern form of RTFM is: Google It.') if k == "firstCondition" else v) for k,v in SOsurvivalConditions.iteritems())