1

I have a dictionary with one key and many values for each key:

d={'POU': ['GL', '1', '999', '4646']
   'TSA': ['LA', '2', '888', '4545']
   'RAS': ['NA', '5', '565', '1316']
   'TSO': ['RA', '7', '575', '1376']}

The second value from each key represents distance(1, 2, 5, 7) in km. And the keys are sorted according to distance.

I want to compare the distance of the following key and discard the keys that are close to each other and have a distance equal or less than 1km. So the final dictionary will be:

d={'POU': ['GL', '1', '999', '4646']
   'RAS': ['NA', '5', '565', '1316']
   'TSO': ['RA', '7', '575', '1376']}   

How can this be done?

What I ve managed to do so far is only to limit the keys according to distance, like:

if (float(d[key][1])<10):

but I can not make it comparing the values of each key with the following one. I am noob with python and I ve been getting crazy with it the last two days.

halfer
  • 19,824
  • 17
  • 99
  • 186
  • 1
    Keys in dictionaries are unsorted. – Scott Hunter Apr 29 '18 at 23:45
  • @user3650827 you can use an OrderedDict type to index key, value pairs. – Ari K Apr 29 '18 at 23:50
  • @Scott Hunter I did it reading a file which has them sorted according to distance. d = {} #with open("hypoinv.err") as f: with open("file.txt") as f: for line in f: key, value = line.split(None, 1) d[key] = (value.split()) #order output as the order in file d=collections.OrderedDict(d) – user3650827 Apr 29 '18 at 23:51
  • @Ari K I tried with: for idx, key in enumerate(d.items()): if ((idx+1, key[1][1]) - (idx, key[1][1]))<1 : print (idx, key[1][1]) But values can not be accessed like that – user3650827 Apr 29 '18 at 23:57
  • `for idx, kv in enumerate(list(d.items()))`. You could use a list for indexing the dict Reference: https://stackoverflow.com/questions/10058140/accessing-items-in-a-ordereddict – Ari K Apr 30 '18 at 00:06

2 Answers2

3

You can iterate through keys and remove them as the condition is matched.

# save keys in a list
vals = list(d.keys())

## count keys
dict_len = len(vals) 

# save keys to be removed
to_rmv = [] 

# iterate through keys
for i in range(dict_len):
    for j in range(i+1, dict_len):
        p = int(d[vals[j]][1])- int(d[vals[i]][1]) ## second index is distance
        if p <= 1:
            to_rmv.append(vals[j])            

## remove keys
for k in to_rmv:
    del d[k]

## see output
print(d)

{'POU': ['GL', '1', '999', '4646'],
 'RAS': ['NA', '5', '565', '1316'],
 'TSO': ['RA', '7', '575', '1376']}
YOLO
  • 20,181
  • 5
  • 20
  • 40
  • 1
    Thanks a lot! It worked! but I had to add a "try" after "for k in to_rmv:" because it found 2 times the same key in my dictionary – user3650827 Apr 30 '18 at 13:22
  • @user3650827 a dictionary with duplicate keys? never heard of that before. Good one. – YOLO Apr 30 '18 at 18:36
2
keys_to_remove = []
for k1, v1 in d.items():
    for k2, v2 in d.items():
        if k1 == k2:
            continue
        dist1 = float(v1[1])
        dist2 = float(v2[1])
        if abs(dist1 - dist2) <= 1:
            keys_to_remove.append(k2)
result = d.copy()
for k in keys_to_remove:
    result.pop(k)
print(result)
Dan
  • 1,874
  • 1
  • 16
  • 21