1

I've been trying to wrap my head over this for the past six hours or so but I've been trying to iterate and slice all keys in a dictionary whilst preserving the values and transfer all items to a new dictionary.

new_dictionary = {}
current_dictionary = {"XXXX1234":43, "XXXX4547":58, "YYYY4948":93, "YYYY5050":45} 
for key,value in current_dictionary.items():
  if current_dictionary not in new_dictionary:
    new_dictionary.update({key[0:4]:value})
print(new_dictionary)

The result should be

{"XXXX":43, "XXXX":58, "YYYY":93, "YYYY":45}

Instead, I get this.

{"XXXX":58, "YYYY":45} 

I don't want to try and convert it into a list and slice it there but I want to find a direct way and I've been scrambling my brains over this for the past afternoon.

VirtualScooter
  • 1,792
  • 3
  • 18
  • 28
  • 6
    Try just putting the literal `{"XXXX":43,"XXXX":58, "YYYY":93,"YYYY":45}` into a Python interpreter and you'll get the same result. Each key in a dictionary has to be unique. You can't have a single key like `"XXXX"` point to both 43 and 58. – Samwise Mar 04 '21 at 03:07
  • 3
    "I've been scrambling my brains over this for the past afternoon" -- I also feel like my brains have been scrambled when I discover that I was trying to do something which is impossible (something which happens to most programmers at times). – John Coleman Mar 04 '21 at 03:29

5 Answers5

3

A key inside a dictionary is unique.
You can put multiple values inside it if you want, but every key has to be unique and therefore which will be overwritten by the new value if you insert it again.

You can make use of list for storing multiple value associated with same key. See below:

>>> current_dictionary = {"XXXX1234":43,"XXXX4547":58, "YYYY4948":93,"YYYY5050":45} 
>>> new_dictionary = {}
>>> for key, value in current_dictionary.items():
...     new_dictionary.setdefault(key[0:4], []).append(value)
... 
>>> print(new_dictionary)
{'XXXX': [43, 58], 'YYYY': [93, 45]}
>>> 
lllrnr101
  • 2,288
  • 2
  • 4
  • 15
1

You can't put duplicate keys in a dictionary. But instead of an error message, Python will write the new values over the old values for the duplicate keys. Consider the results of this fragment (like in the question, but here, I manually sliced each key):

current_dictionary = {"XXXX1234":43, "XXXX4547":58, "YYYY4948":93, "YYYY5050":45}
print(current_dictionary)
# {'XXXX1234': 43, 'XXXX4547': 58, 'YYYY4948': 93, 'YYYY5050': 45}
new_dictionary = {"XXXX":43, "XXXX":58, "YYYY":93, "YYYY":45}
print(new_dictionary)
# {'XXXX': 58, 'YYYY': 45}

Note that the print of new_dictionary shows the second and fourth value from the original dictionary. Also, if you are using an IDE (I use Spyder), the checker/linter will issue a warning on the line where new_dictionary is created.

Now, how could you code this, while still detecting the duplication? Try this for the last section:

new_dictionary = {}
for key,value in current_dictionary.items():
    if key[0:4] not in new_dictionary:
        new_dictionary[key[0:4]] = value
    else:
        print(f"Duplicate key {key[0:4]} with value {value}")
print(new_dictionary)
# Duplicate key XXXX with value 58
# Duplicate key YYYY with value 45
# {'XXXX': 43, 'YYYY': 93}
VirtualScooter
  • 1,792
  • 3
  • 18
  • 28
0

The |= Operator (Python3.9)

I think the |= operator is called the Single Pipe Equals Operator which you can use to combine dictionaries. This adds to left all the entries in right and picking right as tie-breaker.

ids = {"XXXX1234": 43, "XXXX4547": 58, "YYYY4948": 93, "YYYY5050": 45} 
updates = {"XXXX6666": 00, "YYYY5050": 99} # "YYYY5050" is duplicate
updates |= ids # pick right when duplicate key
print(updates)

Output:

{'XXXX1234': 43, 'XXXX4547': 58, 'YYYY4948': 93, 'XXXX6666': 00, 'YYYY5050': 45}

Usually incremental data like len(updates) will be shorter than the complete data like len(ids). Using |= in this way will copy all of ids every time, instead of copying all of updates if was written as ids |= updates.

Unique Keys

As others have noted, you'll want unique keys. This uses 4-digit tail as workaround:

ids = {"XXXX1234": 43, "XXXX4547": 58, "YYYY4948": 93, "YYYY5050": 45} 
new_ids = {key[-4:]: ids[key] for key in ids}
print(new_ids)

Output:

{'1234': 43, '4547': 58, '4948': 93, '5050': 45}
Razzle Shazl
  • 1,287
  • 1
  • 8
  • 20
0

Given:

current_dictionary={"XXXX1234":43,"XXXX4547":58, "YYYY4948":93,"YYYY5050":45} 

As others have said, you cannot create a dict with the same key.

You could make a list of tuples:

>>> [(k[0:4],v) for k,v in current_dictionary.items()]
[('XXXX', 43), ('XXXX', 58), ('YYYY', 93), ('YYYY', 45)]

Or create a dict of lists:

di={}
for k,v in current_dictionary.items():
     di.setdefault(k[0:4],[]).append(v)


>>> di
{'XXXX': [43, 58], 'YYYY': [93, 45]}
dawg
  • 98,345
  • 23
  • 131
  • 206
-1

current_dictionary={"XXXX1234": 43, "XXXX4547": 58, "YYYY4948": 93, "YYYY5050": 45}

new_dictionary = {k[:4]: v for (k, v) in current_dictionary.items()}