1-approximation
1-approximation

Reputation: 321

How to replace all the occurences but one in Python

I have a list of integers of length K.

a = [0, 0, 0, 1, 1, 5]  # length here is 6

I would like to replace all the occurrences of each distinct value in the list by len(a), except for keeping the last value intact. I have three 0, two 1 and one 5. So I will replace two 0 (out of three) by 6, one 1 (out of two) by 6 and that's it.

I would get:

b = [6, 6, 0, 6, 1, 5]

The last 0, the last 1, and the last 5 are retained; the others are replaced by the list length.

I tried to do it this way:

a = [0, 0, 0, 1, 1, 5]
xx = [[i for i, x in enumerate(a) if x == e] for e in range(len(a))]

for i in range(len(a)):
    if len(xx[i]) > 1:
        for j in range(len(xx[i]) - 1):
            a[xx[i][j]] = len(a)

Is there a simpler way to do this ?

Upvotes: 0

Views: 116

Answers (3)

Prune
Prune

Reputation: 77847

Well, if you'd like it in a one-liner:

a = [len(a) if val==a[i+1] else val \
            for i, val in enumerate(a[:-1])] + [a[-1]]

For each element, check to see whether it equals the one after (assumes that a has all equal values contiguous in the list). If so, choose the list length; otherwise, the current value. Do this for all but the last element, which we simply concatenate.

Output:

[6, 6, 0, 6, 1, 5]

Upvotes: 2

con-f-use
con-f-use

Reputation: 4028

If it doesn't have to be the first element, that you keep, I'd do:

seen = []
for i, elm in enumerate(a):
    if elm in seen:
        a[i] = len(a)
    else:
        seen.append(elm)
del seen

This yields

[0, 6, 6, 1, 6, 5]

Upvotes: 1

Fabricator
Fabricator

Reputation: 12772

Here's one way to do it. Use a dict prev to keep track of the index of the previous seen value. If we've seen it, then change it to 6:

a = [0, 0, 0, 1, 1, 5]
prev = {}
for i in range(len(a)):
    if a[i] in prev:
        a[prev[a[i]]] = len(a)
    prev[a[i]] = i

print a

Upvotes: 4

Related Questions