MATIAS VALENZUELA
MATIAS VALENZUELA

Reputation: 23

Python loop multiplicates items

I'm having a very easy problem and I really don't understand why this is happening.

Im learning Python through the website codewars. One of the questions is to separate a sentence and order it by a number that contain each word. For example, if the sentence is "Matias3 I1 a2m" the program should return "I1 a2m Matias3" because of the order of the numbers that contain each word.

This is the code I'm using. It is very simple, but when I assign the new order y[p] = ... the program multiplicates the registers. If I remove that line, the registers are ok and I don't know why.

sentence="is2 Thi1s T4est 3a" #Example of sentence
x=sentence.split(" ") #I create an array with all the words
y= x #I create a second array (y). This is the one I will order by the numbers of the words

for i in range(len(x)): #I make a loop for the array x
  print("i: "+str(i)) 
  for j in range(len(x[i])): #I make a look for each character of the word
    print(" i:"+str(i)+" j:"+str(j)+" "+x[i])
    if x[i][j:j+1].isnumeric(): #If the character is a number, then Id like to put that word in the 
                                #that number position in the y array (of course is the position-1)
      p=int(x[i][j:j+1])-1 # This is the position that the word should be
      y[p]=x[i]  # When I assing y[] to the correct position (I want that the position i                     
                 # becomes the position p, the program get lost)

print(y)

Upvotes: 2

Views: 73

Answers (2)

Light.G
Light.G

Reputation: 7324

What @lain Shelvington said is totally correct. But you may try some code more pythonic below.

sentence="is2 Thi1s T4est 3a"

raw_words_list = sentence.split(' ')
raw_words_dict = {}

for word in raw_words_list:
    for char in word:
        if char.isnumeric():
            raw_words_dict[char] = word

print([raw_words_dict[key] for key in sorted(raw_words_dict.keys())])

Upvotes: 1

colidyre
colidyre

Reputation: 4676

As already commented, the y = x gives you a reference, not a copy of the same list. You need to do y = x.copy() to get the wanted result.

This behaviour is described e.g. in the copy module:

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

But in addition, this function gives you also the result:

print(sorted(sentence.split(), key=lambda e: min(e)))

As you can see, there is already a built-in function sorted() that does everything you want. All you need to do is provide your own sort function. The provided sort function searches for the min-value of the words in the sentence. This is done by the built-in function min().

To complete the task, you have to do one last step: Printing the list as a string again. This can be done via str.join(), see:

>>> sentence = "Matias3 I1 a2m"
>>> print(" ".join(sorted(sentence.split(), key=lambda e: min(e))))
I1 a2m Matias3

Upvotes: 1

Related Questions