Vitor
Vitor

Reputation: 840

Is there a way to replace a certain value in a list that is in another list with a value from a dictionary?

I'm codding a kind of program to encrypt some text using matrices, and I need to replace some numbers in to letters. This is my code so far:

letters = {"1": "A"}
X = [[1, 1, 1],[1, 1, 1]]
for list_in in X:
    for number in list_in:
        new_value = letters[str(number)]
        list_in[number] = new_value
for row in X:
    print(row)

But, I'm getting the following error:

KeyError: 'A'

I have no idea of what is wrong. Sorry if it is a bad question, but I didn't found any question similar to this one.

Upvotes: 1

Views: 363

Answers (2)

Devesh Kumar Singh
Devesh Kumar Singh

Reputation: 20490

The problem in your earlier code is the age-old one Iterating on the list while modifying it, which has caused the exception.

You are modifying list_in in the inner loop while iterating over it when you do list_in[number] = new_value, and this causes new_value to become A in the next loop, which is not a valid key in letters, hence you get the error KeyError: 'A'

I would suggest using list comprehension to achieve what you want, which creates a new list while iterating on the old one, which is what we would like to happen

letters = {"1": "A"}
X = [[1, 1, 1],[1, 1, 1]]

res = [[letters[str(item)] for item in li] for li in X ]
print(res)
#[['A', 'A', 'A'], ['A', 'A', 'A']]

Note that the inner for loop can also be written in another way using map

letters = {"1": "A"}
X = [[1, 1, 1],[1, 1, 1]]

res = [list(map(lambda x:letters[str(x)], li)) for li in X ]
print(res)

Note that this is equivalent to the following traditional double for loops, which might be easier to understand

letters = {"1": "A"}
X = [[1, 1, 1],[1, 1, 1]]

res = []
#Iterate over outer list
for li in X:
    l = []
    #Iterate over inner list and append A for inner list
    for item in li:
        l.append(letters[str(item)])
    #Append this list to a bigger list
    res.append(l)

print(res)

As an addendum, the original code can be made to work by using indexes to change the value instead of replacing items, using enumerate

letters = {"1": "A"}
X = [[1, 1, 1],[1, 1, 1]]

#Iterate over the lists
for i, li in enumerate(X):
    for j, item in enumerate(li):
        #Replace value at index i,j with A
        X[i][j] = letters[str(item)]

print(X)

Upvotes: 2

U13-Forward
U13-Forward

Reputation: 71580

You can use list comprehension with list(map(...)):

print([list(map(lambda x: letters[str(x)], i)) for i in X])

That which outputs:

[['A', 'A', 'A'], ['A', 'A', 'A']]

Upvotes: 1

Related Questions