2016-08-29 1 views
1

eine Wörterbuch-Mapping einer Integerbereich auf einem anderen habe zu finden, als Beispiel:pythonic Art und Weise getrennte ganzzahligen Intervalle im Wörterbuch integer Mapping

data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8} 

Ich möchte alle Regionen finden, wo die numerischen Intervalle in den Werten fehlschlagen zu erhöhen, also sollte meine Ausgabe sein:

Für den obigen Eingang.

Ich denke, meine Antwort wird die Gruppierung Itertools Rezept beschrieben here beinhalten. Ich habe versucht, eine einfache Implementierung von ihm für meine Zwecke zu tun, aber ich bin nicht sicher, wie die Ergebnisse in mein gewünschten Ergebnis zu verwandeln:

from operator import itemgetter 
from itertools import groupby 
data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8} 
for k, pos in groupby(enumerate(data.iteritems()), lambda (i, (a, s)):i - s): 
    print map(itemgetter(1), pos) 

Hat den Ausgang:

[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)] 
[(7, 6)] 
[(8, 6), (9, 7), (10, 8)] 

Welche richtig Gruppen meinen Eingangs Daten, aber gibt mir nicht das Intervall, das ich will. Die Herausforderung, die ich sehe, wenn ich diese Ausgabe in das von mir gewünschte Intervall zerlege, ist, dass sie mir ein Intervall für die 'Überspring-Region' gibt.

+0

Hat das Wörterbuch immer einen Eintrag pro Index? Wenn ja, warum nicht einfach eine Liste verwenden? Wenn nicht: Wie behandelt man Lücken? –

+0

Auch wenn Sie "nicht inkrementieren" sagen, können wir annehmen, dass die Werte in diesen Regionen konstant bleiben, oder könnten sie auch abnehmen? –

+0

Die Werte bleiben in diesen Regionen konstant, sie werden nicht abnehmen. Die Schlüssel sind immer ein ganzzahliger Ganzzahlbereich von '(0, n)', während die Werte monoton ansteigen. Diese Daten könnten leicht als Liste gespeichert werden, nur das andere Werkzeug, das diese Bereiche berechnet, verwendet ein Wörterbuch. Es gibt keinen Grund, dass es nicht konvertiert werden kann. –

Antwort

2

Unter der Annahme, dass die "nicht ansteigenden" Werte in diesen Regionen konstant bleiben und auch nicht abnehmen, können Sie nur Einträge mit demselben Wert gruppieren und dann die Gruppen mit mehr als einem Eintrag auswählen. Schließlich extrahieren Sie den Anfangs- und den Endindex.

>>> data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8} 
>>> items = sorted(data.items()) 
>>> groups = itertools.groupby(items, key=operator.itemgetter(1)) 
>>> ranges = [grp for grp in (list(grp) for key, grp in groups) if len(grp) > 1] 
>>> ranges 
[[(6, 6), (7, 6), (8, 6)]] 
>>> [(r[0][0], r[-1][0]) for r in ranges] 
[(6, 8)] 
1

Wenn dies der Fall ist, die (a) Ihre Schlüssel sind aufeinanderfolgende ganze Zahlen sind und (b) Sie sind die Schlüssel, deren Werte zu finden, nicht größer als der Wert der vorhergehenden ganze Zahl entsprechenden oder nicht weniger als die Wert entsprechend der aufeinanderfolgenden Ganzzahl ist, dann gilt:

>>> [k for k in sorted(data.keys()) if (k-1 in data and not data[k-1] < data[k]) or (k+1 in data and not data[k] < data[k+1])] 
[6, 7, 8] 
0

Hier ist eine alternative Art und Weise unter Verwendung von defaultdict.

from collections import defaultdict 

ranges = defaultdict(list) 
data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8} 
for index, num in data.iteritems(): 
    ranges[num].append(index) 
print [(r[0], r[-1]) for r in ranges.itervalues() if len(r) > 1] 

Ein Vorteil dieses Ansatzes besteht darin, dass es nicht das Wörterbuch Sortierung erfordert.

0

Was ist so etwas wie das:

data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8} 
sd = sorted(data.items()) 
result = [] 
for i in range(1, len(sd)): 
    if sd[i][1] == sd[i-1][1]: 
     result.append(i) 

Ich denke, sorted(data.items()) ist sowohl klarer und pythonic, dass Ihre Schleife

Dies ist das Ergebnis gibt:

print result 
[7, 8] 

, dass eine gute sein könnte Anfang ?

Verwandte Themen