Czy istnieje sposób zmiany nazwy klucza słownika bez ponownego przypisywania jego wartości do nowej nazwy i usuwania starego klucza nazwy; i bez iteracji po kluczu / wartości dict?
W przypadku OragedDict, zrób to samo, zachowując pozycję tego klucza.
python
dictionary
associative-array
ordereddictionary
rabin utam
źródło
źródło
OrderedDict
. dyktaty ignorują porządek, gdy są porównywane dla równości, natomiastOrderedDict
uwzględniają porządek, gdy są porównywane. Wiem, że masz link do czegoś, co to wyjaśnia, ale pomyślałem, że twój komentarz mógł wprowadzić w błąd tych, którzy nie przeczytali tego linku.OrderedDict
przy porównywaniu brany jest pod uwagę porządek” Ok, ale nikogo to nie obchodzi po 3.7. Uważam, żeOrderedDict
jest w dużej mierze przestarzałe, czy możesz podać powody, dla których tak nie jest? np. tutaj nie przekonuje, chyba że potrzebujeszreversed()
Odpowiedzi:
Do zwykłego nagrania możesz użyć:
Wydaje mi się, że w przypadku OrdersDict musisz zbudować zupełnie nowy, korzystając ze zrozumienia.
Modyfikacja samego klucza, jak wydaje się to pytanie, jest niepraktyczna, ponieważ klucze dict są zwykle niezmiennymi obiektami, takimi jak liczby, ciągi znaków lub krotki. Zamiast próbować modyfikować klucz, ponowne przypisanie wartości do nowego klucza i usunięcie starego klucza jest sposobem na osiągnięcie „zmiany nazwy” w pythonie.
źródło
dict.pop
Wydaje mi się, że w przypadku Pythona 3.5 możliwe jest użycie polecenia OragedDict na podstawie mojego testu.OrderedDict
zachowa kolejność wstawiania, czego nie dotyczy pytanie.najlepsza metoda w 1 linii:
źródło
d = {('test', 'foo'):[0,1,2]}
?d[('new', 'key')] = d.pop(('test', 'foo'))
Korzystając z czeku
newkey!=oldkey
, możesz w ten sposób:źródło
dict
zamówieniu, nawet jeśli python3.6 + zainicjuje go w uporządkowanej formie, poprzednie wersje tego nie robią i nie jest to tak naprawdę cecha po prostu efektem zmian w dyktandach py3.6 +. Użyj,OrderedDict
jeśli zależy Ci na porządku.W przypadku zmiany nazwy wszystkich kluczy słownika:
źródło
target_dict.keys()
zagwarantowane jest takie samo zamówienie jak w definicji? Myślałem, że dykton w Pythonie jest nieuporządkowany, a kolejność z widoku kluczy dykta jest nieprzewidywalnaMożesz użyć tego
OrderedDict recipe
napisanego przez Raymonda Hettingera i zmodyfikować go, aby dodaćrename
metodę, ale będzie to złożoność O (N):Przykład:
wynik:
źródło
OrderedDict
go. Ale polecam: Utwórz klasę, która będzie dziedziczyłaOrderedDict
i dodajrename
do niej metodę.Kilka osób przede mną wspomniało o
.pop
sztuczce polegającej na usunięciu i utworzeniu klucza w jednym wierszu.Osobiście uważam, że bardziej wyraźna implementacja jest bardziej czytelna:
Powyższy kod zwraca
{'a': 1, 'c': 2}
źródło
Inne odpowiedzi są całkiem dobre, ale w python3.6 zwykły dict ma również porządek. Trudno więc utrzymać pozycję klucza w normalnym przypadku.
źródło
W Pythonie 3.6 (dalej?) Wybrałbym następującą linijkę
który produkuje
Warto zauważyć, że bez tej
print
instrukcji notebook ipython console / jupyter prezentuje słownik w wybranej przez siebie kolejności ...źródło
Wymyśliłem tę funkcję, która nie mutuje oryginalnego słownika. Ta funkcja obsługuje także listę słowników.
źródło
Korzystam z powyższej odpowiedzi @wim, z dict.pop () podczas zmiany nazw kluczy, ale znalazłem gotcha. Cykliczne przejście przez dykta w celu zmiany kluczy, bez oddzielania listy starych kluczy całkowicie od instancji dict, spowodowało cykliczne wprowadzanie nowych, zmienionych kluczy do pętli i brak niektórych istniejących kluczy.
Na początek zrobiłem to w ten sposób:
Odkryłem, że w ten sposób przechodząc przez dyktat, słownik ciągle znajdował klucze, nawet gdy nie powinien, tj. Nowe klucze, te, które zmieniłem! Musiałem całkowicie oddzielić instancje od siebie, aby (a) uniknąć znalezienia własnych zmienionych kluczy w pętli for i (b) znaleźć niektóre klucze, które z jakiegoś powodu nie zostały znalezione w pętli.
Robię to teraz:
Konwersja my_dict.keys () na listę była konieczna, aby uwolnić się od odniesienia do zmieniającego się dykta. Samo użycie my_dict.keys () utrzymywało mnie przywiązanym do oryginalnej instancji z dziwnymi efektami ubocznymi.
źródło
W przypadku, gdy ktoś chce zmienić nazwy wszystkich kluczy jednocześnie, podając listę z nowymi nazwami:
źródło
@ helloswift123 Podoba mi się twoja funkcja. Oto modyfikacja zmiany nazwy wielu kluczy w jednym wywołaniu:
źródło
Załóżmy, że chcesz zmienić nazwę klucza z k3 na k4:
źródło
TypeError: 'dict' object is not callable
Jeślitemp_dict('k3')
próbujesz odwołać się do wartościk3
klucza, powinieneś użyć nawiasów kwadratowych, a nie nawiasów. Spowoduje to jednak dodanie nowego klucza do słownika i nie zmieni nazwy istniejącego klucza, zgodnie z żądaniem.