Home > Back-end >  Modify item using IN versus Indexing in Python
Modify item using IN versus Indexing in Python

Time:09-30

I'm trying to modify item in a list using IN and Indexing. While modifying via indexing, the item was actually changed. However, when I try to change via IN keyword, it seems that the item in the list does not change.

  • What's the difference between both method internally?
  • When using IN, does it mean that you iterate through the list and assign the value of each item in the variable in for statement?
lines = ['hi', 'hello']

for line in lines:
    line  = '*'

for i in range(len(lines)):
    lines[i]  = '#'

print(lines)
Output:
['hi#', 'hello#']

CodePudding user response:

In the first loop, 'line' is merely a placeholder for value received from lines in each iteration.

Whereas, in the second loop, you're directly referring to the individual elements in the list using their index

lines = ['hi', 'hello']

print(f"Outside the loop - id(lines): {id(lines)}\n")

for line in lines:
    line  = '*'
    print(f"id(line): {id(line)}")
print("\n")
for i in range(len(lines)):
    lines[i]  = '#'
    print(f"id(lines[{i}]: {id(lines[i])}")
    
    
print(f"\n\nid(lines): {id(lines)},id(lines[0]): {id(lines[0])}, id(lines[1]): {id(lines[1])}\n")
print(lines)

Look at the output. You'll notice that id of 'line' is same throughout the loop and it's different from lines[0] and lines[1]. That means, line and lines[0] are not the same and they're located at different locations in the memory.

OUTPUT:

Outside the loop - id(lines): 2831707232384

id(line): 2831707722928
id(line): 2831707722928


id(lines[0]: 2831707976816
id(lines[1]: 2831707977456


id(lines): 2831707232384,id(lines[0]): 2831707976816, id(lines[1]): 2831707977456

['hi#', 'hello#']

CodePudding user response:

The pythonic way is to create a new list and don't try to change elements of a list inplace

lines = ['hi', 'hello']
print([f'{line}#' for line in lines])

Output

['hi#', 'hello#']

Both loops can't change a string. They are immutable in python. Your second loop is assigning a new reference to a new string to the given index.

We can verify that by comparing the id of the strings

lines = ['hi', 'hello']

print(*map(id, lines))
for i in range(len(lines)):
    lines[i]  = '#'
print(*map(id, lines))

print(lines)

Output

139964185810032 139963627798960
139963551752432 139963317214640
['hi#', 'hello#']

Mutable types (for example a list) behave differently

lines = ['hi', 'hello']

lines = [[*i] for i in lines] # convert strings to mutable lists

print(*map(id, lines))
for line in lines:
    line  = ['#']
print(*map(id, lines))

lines = [''.join(i) for i in lines] # convert lists to immutable strings
print(lines)

Output

139963318712752 139963316794224
139963318712752 139963316794224
['hi#', 'hello#']
  • Related