Python “uitbreiden” voor een woordenboek

Wat is de beste manier om een woordenboek uit te breiden met een ander woordenboek zonder het gebruik van een for-lus? Bijvoorbeeld:

>>> a = { "a" : 1, "b" : 2 }
>>> b = { "c" : 3, "d" : 4 }
>>> a
{'a': 1, 'b': 2}
>>> b
{'c': 3, 'd': 4}

Resultaat:

{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 }

Zoiets als:

a.extend(b)  # This does not work

Antwoord 1, autoriteit 100%

a.update(b)

Nieuwste Python-standaardbibliotheekdocumentatie


Antwoord 2, autoriteit 26%

Een prachtig juweeltje in deze gesloten vraag:

De “oneliner-manier”, waarbij geen van de invoerdictaten wordt gewijzigd, is

basket = dict(basket_one, **basket_two)

Meer informatie **basket_two(de **) betekent hier.

In geval van conflict zullen de items van basket_twodie van basket_oneoverschrijven. Zoals oneliners gaan, dit is behoorlijk leesbaar en transparant, en ik heb er geen bezwaar tegen om het te gebruiken wanneer een dictaat dat een combinatie is van twee andere van pas komt (elke lezer die het moeilijk heeft te begrijpen, zal in feite heel goed geholpen worden door de manier waarop dit hem of haar ertoe aanzet om te leren over dicten het **formulier;-). Dus, bijvoorbeeld, gebruikt als:

x = mungesomedict(dict(adict, **anotherdict))

komen redelijk vaak voor in mijn code.

Oorspronkelijk ingediend door Alex Martelli

Opmerking:In Python 3 werkt dit alleen als elke sleutel in basket_two een stringis.


Antwoord 3, autoriteit 9%

Heb je geprobeerd woordenboekbegrip te gebruiken met woordenboektoewijzing:

a = {'a': 1, 'b': 2}
b = {'c': 3, 'd': 4}
c = {**a, **b}
# c = {"a": 1, "b": 2, "c": 3, "d": 4}

Een andere manier om dit te doen is door dict(iterable, **kwarg) te gebruiken

c = dict(a, **b)
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

In Python 3.9 kun je twee dictaten toevoegen met union | telefoniste

# use the merging operator |
c = a | b
# c = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

Antwoord 4, autoriteit 3%

a.update(b)

Zal sleutels en waarden van btot atoevoegen, overschrijven als er al een waarde voor een sleutel is.


Antwoord 5, autoriteit 2%

Zoals anderen al hebben gezegd, zal a.update(b)voor sommige dicts aen bhet resultaat opleveren waar je om hebt gevraagd bij uw vraag. Ik wil er echter op wijzen dat ik de extend-methode voor het toewijzen/instellen van objecten vaak heb gezien dat in de syntaxis a.extend(b), amogen NIET worden overschreven door de waarden van b. a.update(b)overschrijft de waarden van aen is dus geen goede keuze voor extend.

Merk op dat sommige talen deze methode defaultsof injectnoemen, omdat het kan worden gezien als een manier om de waarden van b te injecteren (wat een set standaardwaarden kan zijn ) toevoegen aan een woordenboek zonder waarden te overschrijven die mogelijk al bestaan.

Natuurlijk kun je eenvoudig opmerken dat a.extend(b)bijna hetzelfde is als b.update(a); a=b. Om de toewijzing te verwijderen, kunt u dit als volgt doen:

def extend(a,b):
    """Create a new dictionary with a's properties extended by b,
    without overwriting.
    >>> extend({'a':1,'b':2},{'b':3,'c':4})
    {'a': 1, 'c': 4, 'b': 2}
    """
    return dict(b,**a)

Met dank aan Tom Leys voor dat slimme idee om een dict-constructor zonder neveneffecten te gebruiken voor extend.


Antwoord 6

Je kunt ook de collections.Chainmapvan python gebruiken die werd geïntroduceerd in python 3.3.

from collections import Chainmap
c = Chainmap(a, b)
c['a'] # returns 1

Dit heeft een aantal mogelijke voordelen, afhankelijk van uw gebruik. Ze worden hierin meer detail uitgelegd, maar ik zal een kort overzicht geven:

  • Een kettingkaart gebruikt alleen weergaven van de woordenboeken, dus er worden geen gegevens gekopieerd. Dit resulteert in snellere chaining (maar langzamer opzoeken)
  • Er worden eigenlijk geen sleutels overschreven, dus indien nodig weet je of de gegevens van a of b komen.

Dit maakt het vooral nuttig voor zaken als configuratiewoordenboeken.


Antwoord 7

Als je het nodig hebt als een Klasse, kun je het uitbreiden met dicten de update-methode gebruiken:

Class a(dict):
  # some stuff
  self.update(b)

Other episodes