SUP
SUP

Reputation: 359

Making duplicate values unique in OrderedDict

Have an ordered dict which has duplicate key, value pairings. Want to make those duplicate values unique. For eg. 4244158 & 4244159 combination exist twice I want to keep one of them.

Now the code mentioned below was fine with python2 since ordered dict can be mutated but not with python3 so i made a copy of the ordered dict and compare it with original ordered dict

ordered_parkstop_dict = OrderedDict([('4244162', []),
                                     ('4244158', ['4244159']), 
                                     ('4244159', ['4244158']), 
                                     ('4244157', ['4244160', '4244161']),
                                     ('4244160', ['4244157', '4244161']),        
                                     ('4244161', ['4244157', '4244160'])])
new_ordered_parkstop_dict = ordered_parkstop_dict.copy()
for key, value in ordered_parkstop_dict.items():
    for k,v in ordered_parkstop_dict.items():
        klist = []
        keylist = []
        if value and v:
            if len(v)==1 and len(value)==1:
                klist.append(k), keylist.append(key)
            if (keylist == v) and (klist == value and len(value) == 1):
                new_ordered_parkstop_dict.pop(key)

To clarify, I only want to remove a duplicate of the type x -> [y], y -> [x], i.e. lists with one item.

Upvotes: 2

Views: 1562

Answers (1)

jpp
jpp

Reputation: 164693

Assuming you wish to remove duplicates where you have a single list item, you can adapt the itertools unique_eveseen recipe. The idea is to maintain a set of frozenset items, and add to it only when you meet a list with one item.

from collections import OrderedDict

def unique_everseen(iterable):
    seen = set()
    seen_add = seen.add
    for key, value in iterable:
        if len(value) != 1:
            yield key, value
        else:
            if frozenset((value[0], key)) not in seen:
                seen_add(frozenset((value[0], key)))
                yield key, value

res = OrderedDict(unique_everseen(dd_input.items()))

In Python3, you should under no circumstances iterate over a view such as dict.items while adding / removing items.

Result:

print(res)

OrderedDict([('4244162', []),
             ('4244158', ['4244159']),
             ('4244157', ['4244160', '4244161']),
             ('4244160', ['4244157', '4244161']),
             ('4244161', ['4244157', '4244160'])])

Upvotes: 2

Related Questions