0

What I want to do is to take a string(cipher) and devide it to several groups and not to copy them (assume that every 7 characters to one group), All I want to do is take every 7 letters and add them to one row in two dimentional array and the same for the next 7 and so on.

I have tried to do that with two dimentional array and I have some problem that its always change all my arrays for every update, and I dont want to copy it.

Let me give you an example:

def splitter(cipher,key_length):

    rows = math.ceil(len(cipher)/key_length)
    columns = key_length
    arr = [[""]*columns]*rows
    arr1=[]
    for row in range(rows):
        for column in range(columns):
            if (row * columns + column)< len(cipher):
                arr[row][column] = cipher[row * columns + column]
            else:
                arr[row][column] = ""
        arr1.append(arr[row])
    print(arr1)


splitter("QPWKALVRXCQZIKGRBPFAEOMFLJMSDZVDHXCXJYEBIMTRQWNMEAIZRVKCVKVLXNEICFZPZCZZHKMLVZVZIZRRQWDKECHOSNYXXLSPMYKVQXJTDCIOMEEXDQVSRXLRLKZHOV",7)

the result of the print is that its duplicated the least 7 characters for the all array, and I coudnt figure out why this happening, what I'm missing?

the result of this print is:

[['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', ''], ['Z', 'H', 'O', 'V', '', '', '']]
4

1 Answer 1

1

The problem is this line:

arr = [[""] * columns] * rows

This is a Python "gotcha" - a piece of code which looks on the surface like it should do one thing, but actually does a quite different thing, though the difference is subtle.

What you wanted was a list containing rows different rows. What you actually get is a list containing that many references to the same row. The code [""] * columns only creates one list, so when you fill in the second row's values into that list, it overwrites the first row's values which were previously stored there; then the third row's values overwrite the second row's values, and so on, because they are all references to the same list.

You may find it helpful to visualise the execution step-by-step, to understand what's going on. This link uses the rather excellent Python Tutor tool.


The solution is to create rows different lists explicitly:

arr = [[""] * columns for i in range(rows)]
Sign up to request clarification or add additional context in comments.

1 Comment

might be a duplicate of this: stackoverflow.com/questions/13673060/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.