2013-03-20 12 views
5

Chciałbym zastosować funkcję do wartości dict w miejscu w dict (jak w ustawieniu programowania funkcjonalnego).Modyfikuj wartości dyktujące w miejscu

Powiedzmy mam to dict:

d = { 'a':2, 'b':3 } 

Chcę zastosować funkcję divide by 2.0 do wszystkich wartości dict, co prowadzi do:

d = { 'a':1., 'b':1.5 } 

Jaki jest najprostszy sposób Zrób to?

Używam Python 3.

Edytuj: Jeden liniowiec byłby miły. divide by 2 jest tylko przykładem, potrzebuję funkcji jako parametru.

Odpowiedz

6

można znaleźć mnożyć jeszcze szybciej niż podzielenie

d2 = {k: v * 0.5 for k, v in d.items()} 

Dla wersji stacjonarnej

d.update((k, v * 0.5) for k,v in d.items()) 

W ogólnym przypadku

def f(x) 
    """Divide the parameter by 2""" 
    return x/2.0 

d2 = {k: f(v) for k, v in d.items()} 
+1

Naprawdę myślisz, że pomnożenie będzie znacznie szybsze niż dzielenie? Może w PyPy, gdzie wszystkie koszty, ale arytmetyka skurczyły się do punktu, w którym robi różnicę, ale w CPython założę się, że nie możesz nawet wykryć różnicy ... – abarnert

+0

Sądzę również, że przechodzenie od rozumienia dyktatu do 'd2' zamiast generujących krotek generujących wyrażenie może być w tym przypadku bardziej czytelna (nawet jeśli" marnuje się "na tworzenie nowego słownika). – abarnert

+0

Na marginesie, tak naprawdę nie lubię interpretacji Dict w kodzie python3.x z dwóch głównych powodów - ** 1) ** Twój kod nie jest wstecznie zgodny z python2.6, ** 2) ** Poglądy dyktowania wyglądają trochę zbyt podobnie do ustawiania ze zrozumieniem. (Ja też nie lubię set literałów z tego samego powodu) – mgilson

3
>>> d = { 'a': 2, 'b': 3 } 
>>> {k: v/2.0 for k, v in d.items()} 
{'a': 1.0, 'b': 1.5} 
+3

To tworzy nowy słownik prawo? Tak więc przy ogromnym "dyktowaniu" byłoby to wymagało dużego nakładu zasobów. Czy istnieje sposób, aby po prostu zmodyfikować wartości, nie tracąc przewagi posiadania już zbudowanego 'dyktatu'? (stąd "inplace" w moim pytaniu) – Mic

+0

@Mic Nie martw się o wydajność, chyba że jest problem z wydajnością (i nie mówię, że nie ma, ale * uzasadnij * asercję) - lub utrzymywanie tego samego obiektu jest wymagane z innych powodów semantycznych. Biorąc to pod uwagę, całkowicie zgadzam się z jamylakiem - "inplace" (mutating) i "functional" (immutable) są dość ortogonalne, w zależności od tego, gdzie narysowana jest linia. –

+0

@Mic Prawda, ale kiedy usłyszałem słowo "funkcjonalny", nie sądziłem, że powiesz mi o tym. – jamylak

15

Można pętli klawiszy i ich aktualizacji:

for key, value in d.items(): 
    d[key] = value/2 
+0

Może to być również 1-linijka (jeśli trochę oszukujesz) - 'dla klucza, wartość w d.items(): d [klucz] = wartość/2' – mgilson

+1

Nie myślę otwarcie używając' przedmiotów 'i' value' w tym przypadku zapisuje wszystko w czytelności (lub wydajności, jeśli to ma znaczenie); Odpowiedź Ishpecka wygląda na prostszą (z wyjątkiem twojej lepszej nazwy zmiennej). – abarnert

+0

@mgilson: Jeśli Guido to sugeruje, to nie liczy się jako oszustwo, prawda? (Oczywiście sugeruje to jako "Jeśli musisz mieć to na jednej linii ...") – abarnert

8

powinny pracować dla Ciebie:

>>> d = {'a':2.0, 'b':3.0} 
>>> for x in d: 
...  d[x]/=2 
... 
>>> d 
{'a': 1.0, 'b': 1.5}