am313
am313

Reputation: 1

create new list at every replacement by interative index in python

I have a string str = "abcd"

I want to replace the 1st char of str with "X", append to empty list, replace the 2nd char with "X", append to list, repeat until all elements have been replaced, resulting in the following list of lists:

[['N', 'b', 'c', 'd'],
 ['a', 'N', 'c', 'd'],
 ['a', 'b', 'N', 'd'],
 ['a', 'b', 'c', 'N']]

I've tried:

str = "abcd"
bla = list(str)
blabla = [bla]*len(bla)
for i,e in enumerate(blabla):
    e[i]="N"

I didnt "append" because I dont know how to in this situation. The unwanted result is:

[['N', 'N', 'N', 'N'],
 ['N', 'N', 'N', 'N'],
 ['N', 'N', 'N', 'N'],
 ['N', 'N', 'N', 'N']]

What is the best solution in python 3.5?

Upvotes: 0

Views: 84

Answers (5)

plasmon360
plasmon360

Reputation: 4199

mystr = "abcd"
bla = list(mystr)
old_d =  [bla]* 4

# As others pointed, old_d is list of list of same objects. You can see the memory address of each element

print("memory address for old_d's elements are {}, {}, {}, {}".format(id(old_d[0]), id(old_d[1]),id(old_d[2]),id(old_d[3])))

#call list function as many times as lenfth of the string using list comprehension. 

new_d =  [list(mystr) for i in list(mystr)]    
print("memory address for new_d's elements are {}, {}, {}, {}".format(id(new_d[0]), id(new_d[1]),id(new_d[2]),id(new_d[3])))

for i,_ in enumerate(bla):
    new_d[i][i] = "N"

print new_d

results in:

memory address for old_d's elements is 66070248, 66070248, 66070248, 66070248
memory address for new_d's elements are 135819952, 135819912, 135819872, 135819752
[['N', 'b', 'c', 'd'], ['a', 'N', 'c', 'd'], ['a', 'b', 'N', 'd'], ['a', 'b', 'c', 'N']]

Upvotes: 0

Oleksii Filonenko
Oleksii Filonenko

Reputation: 1653

string = "abcd"

ret = []
for l in range(len(string)):
    t = list(string)
    t[l] = 'X'
    ret.append(t)

print(ret)  # [['X', 'b', 'c', 'd'], ['a', 'X', 'c', 'd'], ['a', 'b', 'X', 'd'], ['a', 'b', 'c', 'X']]

Upvotes: 0

DevLounge
DevLounge

Reputation: 8437

s = 'abcd'

res = []
for i in range(len(s)):
    l = list(s) 
    l[i] = 'N'
    res.append(l)

print res

Upvotes: 0

busybear
busybear

Reputation: 10590

As others point out, your problem is here: blabla = [bla]*len(bla)

blabla points to list bla 4 times. Changes to either element in blabla will change all elements.

If you want to continue with your method, define the list as blabla = [list(bla) for _ in bla]. Otherwise other answers are valid.

Upvotes: 0

Kasravnd
Kasravnd

Reputation: 107287

The following line will create multiple references to same object instead of independent lists, which is why changing one of them will affect the others.

blabla = [bla]*len(bla)

Also don't use python built-in type names and keywords as your argument names.

You don't need to create an empty list before appending your items. Instead you can just use enumerate within a nested list comprehension:

In [42]: [['N' if ind==i else char for ind, char in enumerate(st)] for i in range(len(st))]
Out[42]: 
[['N', 'b', 'c', 'd'],
 ['a', 'N', 'c', 'd'],
 ['a', 'b', 'N', 'd'],
 ['a', 'b', 'c', 'N']]

Upvotes: 1

Related Questions