Diberikan kamus seperti ini:
my_map = {'a': 1, 'b': 2}
Bagaimana seseorang membalik peta ini untuk mendapatkan:
inv_map = {1: 'a', 2: 'b'}
python
dictionary
mapping
reverse
Brian M. Hunt
sumber
sumber
my_map.items()
berfungsiThe order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon
. Tidak ada jaminan itu akan tetap seperti itu jadi jangan menulis kode dengan mengandalkanDict
perilaku yang samaOrderedDict
.Dengan asumsi bahwa nilai dalam dikt adalah unik:
sumber
iteritems()
akan dihasilkan, sehingga dapat diasumsikan bahwa kunci arbitrer akan diberikan untuk nilai yang tidak unik, dengan cara yang tampaknya akan dapat diproduksi kembali dalam beberapa kondisi, tetapi tidak demikian pada umumnya.iteritems()
metode dan pendekatan ini tidak akan berfungsi; gunakan diitems()
sana sebagai gantinya ditunjukkan pada jawaban yang diterima. Juga, pemahaman kamus akan membuat ini lebih cantik daripada menelepondict
.Jika nilai dalam
my_map
tidak unik:sumber
inv_map.get(v, [])
mengembalikan daftar yang sudah ditambahkan jika ada, sehingga tugas tidak diatur ulang ke daftar kosong.setdefault
masih akan lebih cantik.inv_map.setdefault(v, set()).add(k)
.my_map.items()
sebagai gantimy_map.iteritems()
.Untuk melakukan ini sambil mempertahankan jenis pemetaan Anda (dengan asumsi bahwa itu adalah
dict
ataudict
subkelas):sumber
Coba ini:
(Perhatikan bahwa dokumentasi Python pada tampilan kamus secara eksplisit menjamin hal itu
.keys()
dan.values()
elemen-elemennya dalam urutan yang sama, yang memungkinkan pendekatan di atas berfungsi.)Kalau tidak:
atau menggunakan pemahaman dict python 3.0
sumber
Cara lain yang lebih fungsional:
sumber
filter
danmap
harus mati dan dimasukkan ke dalam daftar pemahaman, bukan menumbuhkan lebih banyak varian".dict
dengan tipe pemetaan lain seperticollections.OrderedDict
ataucollections.defaultdict
Ini memperluas jawaban oleh Robert , berlaku ketika nilai-nilai dalam dikt tidak unik.
Implementasinya terbatas karena Anda tidak dapat menggunakan
reversed
dua kali dan mendapatkan yang asli kembali. Itu tidak simetris seperti itu. Ini diuji dengan Python 2.6. Berikut ini adalah contoh penggunaan tentang bagaimana saya menggunakan untuk mencetak dict yang dihasilkan.Jika Anda lebih suka menggunakan a
set
daripada alist
, dan mungkin ada aplikasi yang tidak diurutkan yang artinya ini masuk akal, alih-alihsetdefault(v, []).append(k)
digunakansetdefault(v, set()).add(k)
.sumber
revdict.setdefault(v, set()).add(k)
set
. Ini adalah tipe intrinsik yang berlaku di sini. Bagaimana jika saya ingin menemukan semua kunci di mana nilainya tidak1
atau2
? Maka saya bisa melakukand.keys() - inv_d[1] - inv_d[2]
(dalam Python 3)Kami juga dapat membalikkan kamus dengan kunci duplikat menggunakan
defaultdict
:Lihat di sini :
sumber
Misalnya, Anda memiliki kamus berikut:
Dan Anda ingin mendapatkannya dalam bentuk terbalik:
Solusi Pertama . Untuk membalikkan pasangan nilai kunci dalam kamus Anda, gunakan
for
pendekatan -loop:Solusi Kedua . Gunakan pendekatan pemahaman kamus untuk inversi:
Solusi Ketiga . Gunakan membalikkan pendekatan inversi (bergantung pada solusi kedua):
sumber
dict
dicadangkan dan tidak boleh digunakan untuk nama variabelmy_map
yangdictio()
? Apakah maksud Andadict()
?Kombinasi pemahaman daftar dan kamus. Dapat menangani kunci duplikat
sumber
Jika nilainya tidak unik, dan Anda sedikit hardcore:
Khusus untuk dikt besar, perhatikan bahwa solusi ini jauh lebih efisien daripada jawaban Python membalikkan / membalikkan pemetaan karena berulang
items()
kali berulang.sumber
-1
karena masih menjawab pertanyaan, hanya pendapat saya.Selain fungsi-fungsi lain yang disarankan di atas, jika Anda suka lambdas:
Atau, Anda bisa melakukannya dengan cara ini juga:
sumber
Saya pikir cara terbaik untuk melakukan ini adalah dengan mendefinisikan kelas. Berikut ini adalah implementasi dari "kamus simetris":
Metode penghapusan dan iterasi cukup mudah untuk diterapkan jika diperlukan.
Implementasi ini jauh lebih efisien daripada membalik seluruh kamus (yang tampaknya menjadi solusi paling populer di halaman ini). Belum lagi, Anda dapat menambah atau menghapus nilai dari SymDict Anda sebanyak yang Anda inginkan, dan kamus terbalik Anda akan selalu tetap valid - ini tidak benar jika Anda hanya membalikkan seluruh kamus sekali saja.
sumber
dictresize
, tetapi pendekatan ini menolak Python kemungkinan itu.Ini menangani nilai-nilai non-unik dan mempertahankan banyak tampilan kasing unik.
Untuk Python 3.x, ganti
itervalues
denganvalues
.sumber
Fungsi simetris untuk nilai daftar tipe; Tuples dilindungi ke daftar saat melakukan reverse_dict (reverse_dict (kamus))
sumber
Karena kamus memerlukan satu kunci unik dalam kamus tidak seperti nilai, kami harus menambahkan nilai yang dibalik ke dalam daftar pengurutan untuk dimasukkan dalam kunci spesifik baru.
sumber
Solusi fungsional cepat untuk peta non-bijektif (nilai tidak unik):
Secara teori ini harus lebih cepat daripada menambahkan ke set (atau menambahkan ke daftar) satu per satu seperti dalam solusi imperatif .
Sayangnya nilai-nilai harus diurutkan, pengurutan diperlukan oleh groupby.
sumber
n
unsur-unsur dalam diktik asli, pendekatan Anda memilikiO(n log n)
kompleksitas waktu karena kebutuhan untuk mengurutkan item-item dict, sedangkan pendekatan imperatif naif memilikiO(n)
kompleksitas waktu. Sejauh yang saya tahu pendekatan Anda mungkin lebih cepat sampai besar bukan kepalangdict
dalam praktek , tetapi tentu saja tidak lebih cepat secara teori.Coba ini untuk python 2.7 / 3.x
sumber
Saya akan melakukannya dengan python 2.
sumber
dict.items
(atauiteritems
dengan Python 2) lebih efisien daripada mengekstraksi setiap nilai secara terpisah saat iterasi kunci.Ini akan menghasilkan output sebagai: {1: ['a', 'd'], 2: ['b'], 3: ['c']}
sumber
dict.items
(atauiteritems
dengan Python 2) lebih efisien daripada mengekstraksi setiap nilai secara terpisah saat iterasi kunci. Juga, Anda tidak menambahkan penjelasan pada jawaban yang menduplikasi orang lain.kode ini suka ini:
sumber
Bukan sesuatu yang sama sekali berbeda, hanya resep yang ditulis ulang sedikit dari Cookbook. Lebih lanjut dioptimalkan dengan mempertahankan
setdefault
metode, daripada setiap kali mendapatkannya melalui contoh:Dirancang untuk dijalankan di bawah CPython 3.x, untuk 2.x ganti
mapping.items()
denganmapping.iteritems()
Di komputer saya berjalan sedikit lebih cepat, daripada contoh lain di sini
sumber
dict
dan kemudian mengonversi ke kelas yang diinginkan di akhir (daripada memulai dengan kelas dari jenis yang tepat) tampak bagi saya seperti itu menimbulkan hit kinerja yang sepenuhnya dapat dihindari, di sini.Saya menulis ini dengan bantuan siklus 'untuk' dan metode '.get ()' dan saya mengubah nama 'peta' dari kamus menjadi 'map1' karena 'peta' adalah fungsi.
sumber
Jika nilai tidak unik DAN mungkin berupa hash (satu dimensi):
Dan dengan rekursi jika Anda perlu menggali lebih dalam maka hanya satu dimensi:
sumber
{"foo": "bar"}
ke{'b': ['foo'], 'a': ['foo'], 'r': ['foo']}
dan menimbulkan pengecualian jika nilai apa pun dimyDict
dalamnya tidak dapat diubah. Saya tidak yakin perilaku apa yang Anda coba terapkan di sini, tetapi apa yang sebenarnya Anda implementasikan adalah sesuatu yang tidak diinginkan oleh banyak orang.