2

Considering '1', '2', '3', '4' are the indexes and everything else as the values of a dictionary in Python, I'm trying to exclude the repeating values and increment the quantity field when a dupicate is found. e.g.:

Turn this:

a = {'1': {'name': 'Blue', 'qty': '1', 'sub': ['sky', 'ethernet cable']},
     '2': {'name': 'Blue', 'qty': '1', 'sub': ['sky', 'ethernet cable']},
     '3': {'name': 'Green', 'qty': '1', 'sub': []},
     '4': {'name': 'Blue', 'qty': '1', 'sub': ['sea']}}

into this:

b = {'1': {'name': 'Blue', 'qty': '2', 'sub': ['sky', 'ethernet cable']},
     '2': {'name': 'Green', 'qty': '1', 'sub': []},
     '3': {'name': 'Blue', 'qty': '1', 'sub': ['sea']}}

I was able to exclude the duplicates, but I'm having a hard time incrementing the 'qty' field:

b = {}

for k,v in a.iteritems():
    if v not in b.values():
        b[k] = v

P.S.: I posted this question earlier, but forgot to add that the dictionary can have that 'sub' field which is a list. Also, don't mind the weird string indexes.

Saulo Mendes
  • 115
  • 1
  • 2
  • 9
  • AFAIK, `qty` is stored as a string ... Increment and put it back as a string? – Bhargav Rao Jan 20 '15 at 15:39
  • You should consider editing your previous question, rather than asking a brand new question on *essentially* the same problem. – Ffisegydd Jan 20 '15 at 15:40
  • qty can be stored as a string or int. It's not really important. – Saulo Mendes Jan 20 '15 at 15:42
  • 1
    As a new user, I just found the 'edit' link after creating this new question. Also, as some people had already answered the original question correctly, I followed an user's suggestion and created a new one. Here's the link to the first question: http://stackoverflow.com/questions/28044802/from-a-dictionary-with-repeated-values-how-to-create-a-new-one-excluding-the-re/28045057?noredirect=1#comment44479273_28045057 – Saulo Mendes Jan 20 '15 at 15:45
  • 1
    If you refer to the original question, you will see I've answered your updated question in an edit to my original response. To reiterate what @Ffisegydd said above, I don't think it's good StackOverflow practice to duplicate (to all intents and purposes) a question. – FuzzyDuck Jan 20 '15 at 16:34
  • I suggested asking a new question since the original question was quite different from this answer. The difference might seem small, but since it turned a question about counting into a question of recursive comparison of dictionaries/list as well, I thought a new question would be better. – André Laszlo Jan 21 '15 at 08:25
  • Fair enough André, but I still think an edit to the original question would have been better. I will repost my answer here. – FuzzyDuck Jan 21 '15 at 12:17

2 Answers2

1

First, convert the original dict 'name' and 'sub' keys to a comma-delimited string, so we can use set():

data = [','.join([v['name']]+v['sub']) for v in a.values()]

This returns

['Blue,sky,ethernet cable', 'Green', 'Blue,sky,ethernet cable', 'Blue,sea']

Then use the nested dict and list comprehensions as below:

b = {str(i+1): {'name': j.split(',')[0], 'qty': sum([int(qty['qty']) for qty in a.values() if (qty['name']==j.split(',')[0]) and (qty['sub']==j.split(',')[1:])]), 'sub': j.split(',')[1:]} for i, j in enumerate(set(data))}
FuzzyDuck
  • 1,492
  • 12
  • 14
  • But a dictionary isn't guaranteed to return its items in order. It might output `v['sub']` as `sky,ethernet cable` or as `ethernet cable,sky` – summerbulb Jan 21 '15 at 14:49
  • I don't think that's the case. The value corresponding to the key `'sub'` is a list, which does preserve its order. I think you're confusing this with the fact that the key-value pairs in a `dict` have no particular order, so you can't do e.g. `mydict.keys()` and expect the keys to be in a given order. – FuzzyDuck Jan 21 '15 at 14:54
0

Maybe you can try to use a counter like this:

b = {}
count = 1
for v in a.values():
    if v not in b.values():
        b[str(count)] = v
        count += 1

print b
Tiket_dev
  • 141
  • 1
  • 11