Heisenberg
Heisenberg

Reputation: 115

Why is the output of nested loops in a different order than expected?

This is a program to print each letter of a string along with cordinates of the letter in the matrix.

In this example, the output should be

['s12', 'k12', 'i33', 'l13', 'l13', 'r11', 'a11', 'c13', 'k12']

But I actually get

['r11', 'a11', 's12', 'k12', 'k12', 'l13', 'l13', 'c13', 'i33']
s1 = "skillrack"
mat1 = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
mat2 = [['j', 'k', 'l'], ['m', '.', 'n'], ['o', 'p', 'q']]
mat3 = [['r', 's', 't'], ['u', 'v', 'w'], ['x', 'y', 'z']]
ans = []

for i in range(0, len(mat1)):
  for j in range(0, len(mat1[i])):
    for x in range(0, len(s1)):
      
      if s1[x] == mat1[i][j]:
        ans.append(str(s1[x]) + str(i+1) + str(j+1))
        
      elif s1[x] == mat2[i][j]:
        ans.append(str(s1[x]) + str(i+1) + str(j+1))
        
      elif s1[x] == mat3[i][j]:
        print(mat3[i][j])
        ans.append(str(s1[x]) + str(i+1) + str(j+1))  
       
print(ans) 

The output of ans is shuffled, I need it in the order of s1. How can I do this correctly?

Upvotes: 1

Views: 252

Answers (5)

accdias
accdias

Reputation: 5372

str objects in Python can be indexed and used as arrays.

range() start value already defaults to 0, so there is no need to pass it as the first argument to range().

f-strings are a better option than converting numbers into strings and then concatenating them all together.

Not a requirement but your code will look better if you follow PEP8, Style Guide for Python Code recommendations.

With the above concepts in mind, here is a more Pythonic version of your code, with the fix suggested by @mkrieger1 in his answer:

s1 = 'skillrack'
m1 = ['abc', 'def', 'ghi']
m2 = ['jkl', 'm.n', 'opq']
m3 = ['rst', 'uvw', 'xyz']
ans = []

for c in s1:
    for i, m1i in enumerate(m1):
        for j, m1ij in enumerate(m1i):
            if c == m1ij:
                ans.append(f'{c}{i + 1}{j + 1}')
            elif c == m2[i][j]:
                ans.append(f'{c}{i + 1}{j + 1}')
            elif c == m3[i][j]:
                ans.append(f'{c}{i + 1}{j + 1}')
print(ans)

The code above will give you the following output:

['s12', 'k12', 'i33', 'l13', 'l13', 'r11', 'a11', 'c13', 'k12']

Upvotes: 0

zeeshan12396
zeeshan12396

Reputation: 412

s1="skillrack"
mat1=[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
mat2=[['j', 'k', 'l'], ['m', '.', 'n'], ['o', 'p', 'q']]
mat3=[['r', 's', 't'], ['u', 'v', 'w'], ['x', 'y', 'z']]
ans=[]
for i in range(len(s1)):
   for j in range(len(mat1)):
       for k in range(len(mat1)):
        if s1[i]==mat1[j][k]:
             ans.append(s1[i]+str(j+1)+str(k+1))
        elif s1[i]==mat2[j][k]:
            ans.append(s1[i]+str(j+1)+str(k+1))
        elif s1[i]==mat3[j][k]:
            ans.append(s1[i]+str(j+1)+str(k+1))
            
print(ans)

Upvotes: 0

Matthias
Matthias

Reputation: 13222

To keep the order you could loop over each character in s1 and get the correct value. This differs from your original approach.

def get_code(needle, matrixes):
    for matrix in matrixes:
        for index1, characters in enumerate(matrix, start=1):
            for index2, character in enumerate(characters, start=1):
                if needle == character:
                    return f'{needle}{index1}{index2}'

result = [get_code(character, [mat1, mat2, mat3]) for character in s1]
print(result)

This will give you ['s12', 'k12', 'i33', 'l13', 'l13', 'r11', 'a11', 'c13', 'k12'].

I used a list comprehension to loop over the character of the string and delegated the task of finding the correct value to the function get_code. Since using range for an index access is considered unpythonic I used enumerate to get the index and the matching value.

Upvotes: 1

mkrieger1
mkrieger1

Reputation: 23144

The outermost loop defines the order in which the items appear in the list.

If you want the list to be in the same order as the input string s1, then the loop for x in range(0, len(s1)): must come first:

for x in range(0, len(s1)):
  for i in range(0, len(mat1)):
    for j in range(0, len(mat1[i])):

Upvotes: 1

Sarim Sikander
Sarim Sikander

Reputation: 406

You have to use list comprehension to get a sorted list for your answer like:

print(sorted(l, key=lambda x: int("".join([i for i in x if i.isdigit()]))))

or

print(sorted(l, key=lambda x: int("".join([i for i in x if i.isalpha()]))))

Upvotes: -1

Related Questions