TypeError: unsupported operand tipo(s) di +: ‘dict_items’ e ‘dict_items’

Cerco di riassumere due dizionari genere:

my_new_dict = dict(my_existing_dict.items() + my_new_dict.items())

ma ricevere errore

TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'

Che cosa ho fatto di sbagliato?

  • Nota: Se si desidera eseguire un’iterazione su due dizionari, e sanno di avere le chiavi univoche (o non importa se il processo stesso tasto due volte), considerare l’utilizzo di itertools.catena(dict_a, dict_b)
InformationsquelleAutor JohnDow | 2012-11-13

 

3 Replies
  1. 24

    In python3, dict.items() restituisce un oggetto di tipo dict_items che apparentemente non può essere aggiunto. (in python 2, viene restituito un list che potrebbe essere aggiunto).

    Un modo alternativo per aggiungere un paio di dizionari, che lavora su py2k e py3k:

    d = dict1.copy()
    d.update(dict2)

    Naturalmente, c’è una certa ambiguità su ciò che si vuole che accada nel caso di chiave di collisioni. ad esempio, se entrambi dicts hanno key1, la cui key1 deve essere conservato in uscita? O è necessario utilizzare una combinazione di entrambi i loro valori? In quest’ultimo caso, probabilmente si vorrà qualcosa da collections modulo (o defaultdict o Counter)

    • grazie, funziona! Io odio 2.7>3.2 la migrazione…
    • si veramente dovrebbe leggere documenti.
    • Penso che dict.items() in 3+ è l’equivalente di dict.iteritems() 2.6, che è, è un iteratore.
    • No, restituisce un dizionario, che è un set-come contenitore (vedi la mia risposta).
    • beh, io trovo corretto (e più imparato…)
    • È buona per imparare qualcosa di nuovo ogni giorno :).

  2. 28

    Dal PEP 448 (Python 3.5), c’è una molto semplice e leggibile soluzione che mi sento di raccomandare:

    {**d1, **d2}

    È ora possibile fornire unpackings in valori letterali e più unpackings, il che significa che questo funziona.

    Un problema è il comportamento che si desidera è ambiguo – dizionari non può avere un duplicato delle chiavi, quindi non è chiaro che cosa si vuole che accada se entrambi contengono la stessa chiave. La spec è esplicito su ciò che dovrebbe accadere quando si utilizza questo metodo:

    Nei dizionari, poi sempre valori ignorare quelle precedenti

    Se si desidera che l’inversione di comportamento, si può semplicemente scambiare l’ordine dei dizionari letterale. Se si desidera generare un’eccezione, è possibile utilizzare il dict() metodo che non accetta argomenti duplicati, io.e:

    dict(**d1, **d2)

    Nelle vecchie versioni di Python 3, il tuo approccio è valido, ma il problema qui è che dizionario di vista sono come, quindi non hanno inoltre implementato.

    Quello che probabilmente è la unione: d1.items() | d2.items(), che vi darà un insieme di tuple di (key, value). Se poi si passa a dict() e ci sono duplicati, gli “ultimi” valore sarà utilizzato, stabilisce tuttavia (a differenza il punto di vista di se stessi) sono non ordinato, quindi non c’è garanzia che la voce di finire “prima” nell’insieme”, nel senso che si “vince” sarà arbitrario.

    Così, in breve, come lungo come ordine/duplicato di selezione non è importante:

    dict(d1.items() | d2.items())

    Nota che in Python 2, dict.items() restituisce semplicemente un list, dove il vostro metodo di lavoro.

    • Quando provo questo ho: TypeError: unhashable type: 'dict'
    • salvagente! bel trucco, il mio amico!
    • Con Python 3.6.1, ho notato che se un elemento è in entrambi i d1 e d2, sembra dict(d1.items() | d2.items()) risultati in d1‘s elementi valida in caso di duplicati, che non è quello che mi aspettavo. dict(list(d1.items()) + list(d2.items())) si comporta come mi aspetto, con d2 vincita in caso di duplicati.
    • Sì, di insiemi non ordinati, mentre i dizionari sono (ora) ordinato. Il mio testo è stato fuorviante, in quanto “ultimo” non significa molto quando i set sono ordinati in modo arbitrario. Se si desidera mantenere l’ordine, è infatti necessario utilizzare una raccolta ordinata come una lista (con un piccolo costo aggiuntivo di costruzione).
    • Vedere la mia ultima modifica di aggiornamento dell’approccio credo sia l’opzione migliore in tutti i casi.
    • Molto fresco, @GarethLatty! Grazie per l’aggiornamento la vostra risposta.

  3. 2

    Un altro approccio alle altre risposte è:

    dict(list(d1.items()) + list(d2.items()))

    Se ci sono le chiavi presenti in entrambi d1 e d2, il valore in d2 saranno utilizzati nel finale dizionario.

Lascia un commento