Reputation: 1
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
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
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
Reputation: 8437
s = 'abcd'
res = []
for i in range(len(s)):
l = list(s)
l[i] = 'N'
res.append(l)
print res
Upvotes: 0
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
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