How to replace a element in a nested List in Python
Question:
I can locate any listed content. In the example I locate ‘q’. I manually mapped its index as [1][0][1][1]
. Then I replaced it with ‘z’ and it works. My question is what is the magic to get the index(q) or Object Address(q) when the if() condition get set to True?
import ctypes
lis = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
idLis = id(lis)
if 'q' in str(lis):
idLisContent = ctypes.cast(idLis, ctypes.py_object).value
print("List Content: = ", idLisContent)
print("Index 0 = ", idLisContent[0])
print("Index 1 = ", idLisContent[1])
qId = id(idLisContent[1][0][1][1])
print("Index Q = ", ctypes.cast(qId, ctypes.py_object).value)
idLisContent[1][0][1][1] = 'z'
print("List Content: = ", idLisContent)
exit(1)
Output:
List Content: = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
Index 0 = ['a', ['b'], 'c']
Index 1 = [['d', ['p', ['q']]], 'e', 'f']
Index Q = ['q']
List Content: = [['a', ['b'], 'c'], [['d', ['p', 'z']], 'e', 'f']]
Answers:
Just convert it to string and replace ‘q’ to ‘z’
lis = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
str_lis = str(lis).replace('q', 'z');
print str_lis;
I offer a true method to replace the value of a multidimensional array instead of converting it to a string first as stated in this accepted answer. Of course, these ways use a recursive function to get the index of the value in the multidimensional array and to replace that with another value using the index.
from copy import deepcopy
def getAllIndex(val, depth):
if type(val) is str:
allIndex[val] = deepcopy(depth)
for i, j in enumerate(val):
if type(val) is list:
depth.append(i)
getAllIndex(j, depth)
depth.pop()
def getValue(val, index):
if type(val) is str:
return val
else:
return getValue(val[index[0]], index[1:])
def replaceValue(val, string, index):
if len(index) == 1:
val[index[0]] = string
else:
replaceValue(val[index[0]], string, index[1:])
lis = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
print("List Content: = ", lis)
print("Index 0 = ", lis[0])
print("Index 1 = ", lis[1])
allIndex = {}
getAllIndex(lis, []) # returns {'a': [0, 0], 'b': [0, 1, 0], 'c': [0, 2], 'd': [1, 0, 0], 'p': [1, 0, 1, 0], 'q': [1, 0, 1, 1, 0], 'e': [1, 1], 'f': [1, 2]}
indexQ = allIndex['q'] # get index of 'q'
print("Index Q = ", indexQ) # index of 'q' = [1][0][1][1][0] represent as [1, 0, 1, 1, 0]
print("Value of",indexQ,"=",getValue(lis, indexQ)) # get value of lis[1][0][1][1][0]
replaceValue(lis, 'z', indexQ) # replace specific value e.g. 'q' => 'z' with index of 'q'
print("List Content: = ", lis)
The output will be:
List Content: = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
Index 0 = ['a', ['b'], 'c']
Index 1 = [['d', ['p', ['q']]], 'e', 'f']
Index Q = [1, 0, 1, 1, 0]
Value of [1, 0, 1, 1, 0] = q
List Content: = [['a', ['b'], 'c'], [['d', ['p', ['z']]], 'e', 'f']]
I can locate any listed content. In the example I locate ‘q’. I manually mapped its index as [1][0][1][1]
. Then I replaced it with ‘z’ and it works. My question is what is the magic to get the index(q) or Object Address(q) when the if() condition get set to True?
import ctypes
lis = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
idLis = id(lis)
if 'q' in str(lis):
idLisContent = ctypes.cast(idLis, ctypes.py_object).value
print("List Content: = ", idLisContent)
print("Index 0 = ", idLisContent[0])
print("Index 1 = ", idLisContent[1])
qId = id(idLisContent[1][0][1][1])
print("Index Q = ", ctypes.cast(qId, ctypes.py_object).value)
idLisContent[1][0][1][1] = 'z'
print("List Content: = ", idLisContent)
exit(1)
Output:
List Content: = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
Index 0 = ['a', ['b'], 'c']
Index 1 = [['d', ['p', ['q']]], 'e', 'f']
Index Q = ['q']
List Content: = [['a', ['b'], 'c'], [['d', ['p', 'z']], 'e', 'f']]
Just convert it to string and replace ‘q’ to ‘z’
lis = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
str_lis = str(lis).replace('q', 'z');
print str_lis;
I offer a true method to replace the value of a multidimensional array instead of converting it to a string first as stated in this accepted answer. Of course, these ways use a recursive function to get the index of the value in the multidimensional array and to replace that with another value using the index.
from copy import deepcopy
def getAllIndex(val, depth):
if type(val) is str:
allIndex[val] = deepcopy(depth)
for i, j in enumerate(val):
if type(val) is list:
depth.append(i)
getAllIndex(j, depth)
depth.pop()
def getValue(val, index):
if type(val) is str:
return val
else:
return getValue(val[index[0]], index[1:])
def replaceValue(val, string, index):
if len(index) == 1:
val[index[0]] = string
else:
replaceValue(val[index[0]], string, index[1:])
lis = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
print("List Content: = ", lis)
print("Index 0 = ", lis[0])
print("Index 1 = ", lis[1])
allIndex = {}
getAllIndex(lis, []) # returns {'a': [0, 0], 'b': [0, 1, 0], 'c': [0, 2], 'd': [1, 0, 0], 'p': [1, 0, 1, 0], 'q': [1, 0, 1, 1, 0], 'e': [1, 1], 'f': [1, 2]}
indexQ = allIndex['q'] # get index of 'q'
print("Index Q = ", indexQ) # index of 'q' = [1][0][1][1][0] represent as [1, 0, 1, 1, 0]
print("Value of",indexQ,"=",getValue(lis, indexQ)) # get value of lis[1][0][1][1][0]
replaceValue(lis, 'z', indexQ) # replace specific value e.g. 'q' => 'z' with index of 'q'
print("List Content: = ", lis)
The output will be:
List Content: = [['a', ['b'], 'c'], [['d', ['p', ['q']]], 'e', 'f']]
Index 0 = ['a', ['b'], 'c']
Index 1 = [['d', ['p', ['q']]], 'e', 'f']
Index Q = [1, 0, 1, 1, 0]
Value of [1, 0, 1, 1, 0] = q
List Content: = [['a', ['b'], 'c'], [['d', ['p', ['z']]], 'e', 'f']]