Weird response with enumerate and dict in python

80 views Asked by At

Using the dict(enumerate(x)), we get the { (index, value) }. Instead, I need { (value, index) }. So, I've written this code...

idx= { n:i for i, n in enumerate(x)}

It works with some inputs and fails with others. Here's an input where it is failing.

x= [73,74,75,71,69,72,76,73]

, Why is it failing? and what should be done?

2

There are 2 answers

0
JonSG On BEST ANSWER

Why is it failing?

We know that for:

x = [73,74,75,71,69,72,76,73, 99]  # note the additional list item

The result:

{73: 7, 74: 1, 75: 2, 71: 3, 69: 4, 72: 5, 76: 6, 99: 8}

is "bad" for at least the first key in the dictionary. The reason it is bad (as others have pointed out) is that there are duplicate entries in the list x and as we process them we are conceptually doing:

idx = {}
idx[73] = 0
idx[73] = 7
print(idx)

What should be done?

We don't know what you actually expect for the key of 73. I think there is a good chance you want the value 0 but perhaps you want the value [0, 7] showing both indexes of 73 in the original list.

The other wrinkle is not knowing how the additional item 99 (occurring after the duplicated 73) should be assigned a value. Do we keep the existing index entry 8 or do we want that to be a new 7 effectively replacing the duplicate?

Determining how to get some other result is fairly straight forward and I'll give you several things you can try.

Option 1:

I want the keys to have their actual first list indexes:

73 --> 0
99 --> 8
idx_expected = {73: 0, 74: 1, 75: 2, 71: 3, 69: 4, 72: 5, 76: 6, 99: 8}
idx_actual = {}
for index, value in enumerate(x):
    if value not in idx_actual:
        idx_actual[value] = index
print(idx_actual == idx_expected)

Option 2:

I want the keys to have their first list indexes but if there is a duplicate, I just want to pretend it did not exist:

73 --> 0
99 --> 7
## -------------
idx_expected = {73: 0, 74: 1, 75: 2, 71: 3, 69: 4, 72: 5, 76: 6, 99: 7}
idx_actual = {n:i for i, n in enumerate(dict.fromkeys(x))}
print(idx_actual == idx_expected)
## -------------

Option 3:

I want to capture the fact that there could be duplicates in the original list by setting the values in the resulting dictionary to a list of original indexes.

73 --> [0, 7]
99 --> [8]
## -------------
idx_expected = {73: [0, 7], 74: [1], 75: [2], 71: [3], 69: [4], 72: [5], 76: [6], 99: [8]}
idx_actual = {}
for index, value in enumerate(x):
    idx_actual.setdefault(value, []).append(index)
print(idx_actual == idx_expected)
## -------------
1
Roger V. On

73 is contained twice in vector x= [73,74,75,71,69,72,76,73], which results in ambiguity (the same key corresponds to two different index values.)