Home > OS >  Is there a way to write a for each in python3 that modifies the array?
Is there a way to write a for each in python3 that modifies the array?

Time:02-16

Let's say for example that I have an array that represents a name and I want to use just the first letter of any part of a name that is not the first or the last part:

# Have
name = ["John", "Banana", "Doe"]

# Want
["John", "B", "Doe"]

Can I iterate through a subset of an array and change the variables inside it through the variable that references it like so?

for part in name[1:-1]:
    part = part[0]

The only solution I fould for this was to use list comprehention, but it was too hard to read:

name = [part if i in [0, len(name)-1] else part[0] for i, part in enumerate(name)]

CodePudding user response:

v = v[0] reassigns the name v, that was previously bound to one of the list elements. This does not mutate the list, though.

You could fix your loop by iterating over an index range and explicitly reassign list elements.

for index in range(1, len(name) - 1):
    name[index] = name[index][0]

An easier to read list-comprehension solution would be:

name[1:-1] = [v[0] for v in name[1:-1]]

An equivalent solution without a list comprehension would be:

new_values = []

for v in name[1:-1]:
    new_value = v[0]
    new_values.append(new_value)

name[1:-1] = new_values

Bonus: repeating [1:-1] twice is not as clean as it could be. You could define a slice object to refer to the desired part of the list, e.g.

where = slice(1, -1)
name[where] = [v[0] for v in name[where]]

CodePudding user response:

start = 1
for i,v in enumerate(name[start:-1]):
    name[i start] = v[0]

Or something slightly cleaner, using what I just learned about enumerate:

start = 1
for i,v in enumerate(name[start:-1],start):
    name[i] = v[0]

CodePudding user response:

What about using enumerate with a set?

name = ["John", "Banana", "Doe"]

pos = {0, len(name)-1}

[w if i in pos else w[0] for i,w in enumerate(name)]

or with a classical loop (but without explicit check, the list should have more than 1 element):

out = name[:1]

for i in range(1, len(name)-1):
    out.append(name[i][0])

out.append(name[-1])

CodePudding user response:

You can do this

for i,v in enumerate(name[1:-1]):
   name[i] = v[0]

What you can't do while iterating over a list is changing the list size, but changing the content is allowed.

  • Related