2012-04-13 2 views
2

Ich habe ein Diktat mit Floats als Schlüssel und Objekte als Werte. Ich erhalte einen Float, und ich möchte wissen, zwischen welchen zwei Schlüsseln dieser Float ist. Wie finde ich das?Die beiden nächsten Zahlen zu einem Float aus einer Liste herausfinden

Beispiel dessen, was ich in Code bedeuten:

a = {} 
a[1.2] = some_unimportant_instance 
a[2.3] = some_other_unimportant_instance 
a[2.6] = some_third_unimportant_instance 
etc... 

r = 2.5 
# a[r] will not work 
# I want something that returns the two numbers around r 
# in this case, 2.3 and 2.6. 

Antwort

7

Erste Beobachtung: dict-s sind für diese schlecht. Sie werden mithilfe von Hashes implementiert und eignen sich nur zum Abrufen von Werten für exakte Übereinstimmungen. Für Ihren Zweck müssten Sie zuerst das Diktat in eine Liste von Schlüsseln umwandeln. Dann könnten Sie Module wie zum Beispiel halbieren.

Beispiel:

import bisect 
keys = sorted(a.keys()) 
index = bisect.bisect(keys, r) 
if index >= 1: 
    print keys[index - 1] 
print keys[index] 

UPDATE: Code verbessert, wie von Mark Dickinson vorgeschlagen. Vielen Dank!

+1

Ich würde einen Schritt weiter gehen und sagen, dass ein besseres Modell eine sortierte Liste von Tupeln ist, da Sie jedes Mal (zumindest teilweise) die Liste durchlaufen müssen. –

+0

@ D.Shawley: Ich zweite Sekunde. – user1202136

+0

Wäre nicht 'keys = sortiert (a.keys())' besser? Willst du auch nicht 'index> = 1' anstatt 'index> 1'? Sie könnten auch den doppelten Aufruf von bisect.bisect in der letzten Zeile loswerden. –

0

Um die beiden Tasten tatsächlich zurückkehren, bedenken Sie:

def surrounding_keys(needle, haystack): 
    if haystack: # ensure it's not empty 
     keys = sorted(haystack.keys()) 
     for (lower, upper) in zip(keys, keys [1:]): 
      if lower < needle < upper: 
       return (lower, upper) 
    raise KeyError # fails with key error if: not found, empty dict, dict with only one key 
4

Es ist Pythonic PyPI zu verwenden. Es gibt eine Reihe von MutableMapping-Typen, die die Schlüssel in sortierter Reihenfolge verwalten und die gewünschte Halbierung und Indizierung unterstützen. Betrachten Sie das sortedcontainers Modul, das einen SortedDict Typ für genau diesen Zweck hat.

from sortedcontainers import SortedDict 
sd = SortedDict((key, value) for key, value in data) 

# Get the would-be index of the desired key. 
index = sd.bisect(2.5) 

# Get the actual key at that index. 
key = sd.iloc[index] 

# Look ahead one to find the range. 
ahead = sd.iloc[index + 1] 

sortedcontainers ist auch pure-Python, kompatibel mit 2.6 bis 3.4, verfügt über 100% Testabdeckung und Stunden von Stress und hat ein benchmark comparison es zeigt wirklich schnell zu sein (schnell-wie-C-Implementierungen schnell) .

Verwandte Themen