1

I have a dictionary of the type d1={"url1":0, "url2":1, ...}. I then have two more dictionaries in the same format that contain different URLs, but the values still start from 0. Is there a way to combine the dictionaries so that the numbers automatically change and I have a dictionary that has no-repeat values (ie each URL has a unique number after addition). I tried .update() but I don't think that it works for my purpose.

In terms of adding a clearer example, the code looks something like this:

d1 = {"url1":0, "url2":1}
d2 = {"url3":0, "url4":1}
d3 = {"url5":0, "url6":1}

I want a function that will combine these dictionaries and give me:

d4 = {"url1":0, "url2":1, "url3":2, "url4":3, "url5":4, "url6":5}

I tried d1.update(d2) and then d1.update(d3), but those did not seem to work.

Rohan Bansal
  • 31
  • 1
  • 2
  • Did you try searching with `python combine dictionaries`? – wwii Apr 12 '20 at 15:11
  • Yeah, I don't see this type of case. If you know of a thread, please do link it. – Rohan Bansal Apr 12 '20 at 15:13
  • Cannot tell from your explanation what you are trying to do. You should include minimal examples of the dictionaries you want to combine and what you expect as a result and the code you tried that does not work. Please read [mcve]. – wwii Apr 12 '20 at 15:14
  • I updated the question to make it clearer – Rohan Bansal Apr 12 '20 at 15:30

3 Answers3

1

Try this:

def append_di(d_to, d_from):
    start = len(d_to)
    for k in d_from:
        if k not in d_to: 
           d_to[k] = start
           start += 1

di = {"url1":0, "url2":1}
di_2 = {"url3":0, "url4":1, "url1":2}
append_di(di, di_2)
print(di)

Outputs:

{'url1': 0, 'url2': 1, 'url3': 2, 'url4': 3}

Using dict comprehension:

di = {"url1":0, "url2":1}
di_2 = {"url3":0, "url4":1, "url1":3}
di.update({k:(len(di) + i) for i,k in enumerate(di_2) if k not in di})
print(di)
abhiarora
  • 9,743
  • 5
  • 32
  • 57
  • Thanks for the answer, that seems to work, although I'm not sure how efficient it is. Also, does this method work if there are duplicate keys in the dictionaries. – Rohan Bansal Apr 12 '20 at 15:26
  • That's the different story, you should add your code too so that we can discuss on efficiency but this question was about logic implementation only. – abhiarora Apr 12 '20 at 15:31
  • Ok, so these don't work with duplicates (ie if the key already exists in the original dictionary keep the old value and only add if it is new) – Rohan Bansal Apr 12 '20 at 15:41
  • Hope that have resolved your question. Let me know in case it is not working! – abhiarora Apr 12 '20 at 16:49
0

I am not sure I am clear on the nuances of the functionality you are looking for, but this may suit your needs:

dicts = [d1,d2,d3]
keys = [k for d in dicts for k in d.keys()]
d4 = dict(zip(keys, range(len(keys))))

Note that it does not do anything to order the keys. Also, if redundant keys are present the first key supplied will be overwritten by later keys. This will result in gaps in the indexing scheme.

This solution is fairly simple, but if you want a higher degree of control I suggest using a loop such as suggested by @abhiarora.

corvus
  • 556
  • 7
  • 18
  • This doesn't work for me, it just combines the dictionaries without updating the values as I wanted in the question. – Rohan Bansal Apr 12 '20 at 15:36
  • @RohanBansal I see that I misunderstood what you are trying to do. Is it important which url gets which index, i.e. `url1:0`, `url2:1`, etc? Or is it only important that each url has a unique index? Also do you want existing entries to be overwritten if there are conflicting keys? – corvus Apr 12 '20 at 15:53
  • No, it doesn't matter as long as each one has a unique index. Also, I would prefer that existing values are not overwritten and instead are just kept as the original value. – Rohan Bansal Apr 12 '20 at 16:46
0

Assuming you are using a version of Python that maintains insertion order for dicts AND you just want the values to begin at zero and increase by one for each key:

d1 = {"url1":0, "url2":1}
d2 = {"url3":0, "url4":1}
d3 = {"url5":0, "url6":1, 'url1':2}

new = dict.fromkeys(k for d in [d1,d2,d3] for k in d.keys())
for i,k in enumerate(new):
    new[k] = i

k for d in [d1,d2,d3] for k in d.keys() flattens the sequence of keys from each dict.
Constructing a new dictionary using fromkeys() eliminates the duplicates.


>>> new
{'url1': 0, 'url2': 1, 'url3': 2, 'url4': 3, 'url5': 4, 'url6': 5}
>>> 
wwii
  • 23,232
  • 7
  • 37
  • 77