2

I have the following list:

labels = [fixed acidity', 'volatile acidity', 'citric acid]

I want to replace the empty spaces between the words of the list items with "_"

Code1 is working, the first output of Code2 looks fine, but the second does not.

Code1:

    labels[0] = labels[0].replace(' ', '_')
    labels[1] = labels[1].replace(' ', '_')
    labels[2] = labels[2].replace(' ', '_')

Code2:

for label in labels:
    label = label.replace(' ','_')
    print(label)

print(labels)

Output of print(label): fixed_acidity volatile_acidity citric_acid

the output of print(labels): ['fixed acidity', 'volatile acidity', 'citric acid']

Any idea what went wrong?

user78910
  • 349
  • 2
  • 12
Bliso
  • 23
  • 3
  • 1
    ``label`` is just *a separate name* referring to each element. It is neither the element itself (reassigning ``label`` does not change the element) nor is it the position in the list (``label`` and ``labels[0]`` just *point to* the same element at some time). – MisterMiyagi Jun 03 '20 at 19:03
  • Does this answer your question? [Are python variables pointers? or else what are they?](https://stackoverflow.com/questions/13530998/are-python-variables-pointers-or-else-what-are-they) – MisterMiyagi Jun 03 '20 at 19:05

7 Answers7

4

Change values and set value of list again :

labels = [i.replace(" ", "_") for i in labels]
Tahirhan
  • 352
  • 1
  • 7
  • 15
1
labels = ['fixed acidity', 'volatile acidity', 'citric acid']
for num, label in enumerate(labels):
    labels[num] = label.replace(' ', '_')
    print(label)

print(labels)
Ne1zvestnyj
  • 1,391
  • 1
  • 7
  • 25
1

Or the lambda way:

listBefore = [...]
listAfter = list(map(lambda x: x.replace(" ", "_"), listBefore))
Sofien
  • 478
  • 3
  • 12
  • 1
    its great that you can write it using lambda however inline functions with map are a little slower than list comprehensions. maps are faster with defined functions rather than inline lambda. Hope this is useful – Aditya Patnaik Jun 03 '20 at 19:23
  • @aditya: this information is useful, even though it makes sense, I always do it this way, if the list isn't too long, because the timing difference is so little that I never felt the difference. But anyways, thanks for this comment! :) – Sofien Jun 04 '20 at 12:40
0

Try it

for label in range(len(labels)):
    labels[label] = labels[label].replace(' ','_')
    print(label)

print(labels)
dimay
  • 2,768
  • 1
  • 13
  • 22
0

The following solution:

labels = ['fixed acidity', 'volatile acidity', 'citric acid']
new_labels = []
for i in range(len(labels)):

    label = labels[i].split(' ')

    new_labels.append(label[0]+'_'+label[1])


print(new_labels)

output:

['fixed_acidity', 'volatile_acidity', 'citric_acid']
Dejene T.
  • 973
  • 8
  • 14
0

It's because you're actually creating a copy once you apply the replace function. To see this, look at the output of this:

for label in labels:
    print(id(label))
    label = label.replace(' ','_')
    print(id(label), "\n")

print(labels)
print([id(label) for label in labels])

Note how the identity is different once you've changed label so you're not changing the list, you change a copy of the element of the list.

In order to actually change the list through a for-loop, you would need to then set the value in the list at the correct index, like this:

for i, label in enumerate(labels):
    labels[i] = label.replace(' ','_')
ap1997
  • 183
  • 6
0

Simply use Replace in a loop and store it as a generator for lazy evaluation!

gen = (i.replace(" ","_") for i in labels) # returns a generator to iterate over.
# gen_to_list = list(gen) change it into a list only when its really necessary.

You can iterate over a generator like a list, the only difference is that a generator takes way less space than a list.

  • a generator with 1000 numbers takes 80 bytes
  • a list with 1000 numbers takes 9032 bytes

Compare and use.enter image description here

Memory Stats on around 1400 strings implemented using lists / generator.

Aditya Patnaik
  • 1,490
  • 17
  • 27