Search code examples
pythonarrayspython-3.xmultidimensional-arraysections

How to define section number that 2d-array is divided to using Python?


I have this data structure:

enter image description here

It is 2d-array that is divided on 3 sections. For each letter in the array I need to define Section number. For example, letters a,b,c,d are in Section 1; e,f,g,h are in Section 2.


My code. Firstly, this 2d-array preparation:

from itertools import cycle
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']

#2d-array initialization  
width, height = 3, 6 
repRange = cycle(range(1, 3))
values = [0] * (width - 1)
array2d = [[next(repRange)] + values for y in range(height)]

#Filling array with letters:
m = 0
for i in range(height):
    for j in range(1,width):
       array2d[i][j] = letters[m] 
       m+=1

#Printing:      
for row in array2d:
    print(row)

Output:

[1, 'a', 'b']
[2, 'c', 'd']
[1, 'e', 'f']
[2, 'g', 'h']
[1, 'i', 'j']
[2, 'k', 'l']

Now I need to determine section number of each letter and save it along with the letter itself. I use defineSection function and save values in dictionary:

def defineSection(i, division, height):
    if i <= division:
        return 1
    elif division*2 >= i > division :
        return 2
    elif division*3 >= i > division*2 :
        return 3   

dic = {}
for i in range(height):
    for j in range(1,width):
        section = defineSection(i+1, 2, height)
        dic.update({array2d[i][j] : section})

for item in dic.items():
    print(item)

Output:

('f', 2)
('b', 1)
('c', 1)
('e', 2)
('k', 3)
('g', 2)
('d', 1)
('a', 1)
('l', 3)
('h', 2)
('i', 3)
('j', 3)

It defined all section numbers for each letter correctly. But defineSection method is primitive and will not work if number of rows is bigger than 6. I don't know how to implement defineSection method so that it defines Section number automatically taking into account only current Row number, division and number of rows in total.


Question: Is there some way I can simply determine section number without so many if-elif conditions and independently of total number of rows?


Solution

  • You can simplify your matrix creation code immensely. All you need is a letters iterator, which returns itself so you can iterate 2-letters at a time using zip.

    In [3]: from itertools import cycle
    
    In [4]: letters = "abcdefghijkl"
    
    In [5]: ranges = cycle(range(1,3))
    
    In [6]: iter_letters = iter(letters)
    
    In [7]: matrix = [[i,a,b] for i,a,b in zip(ranges,iter_letters,iter_letters)]
    
    In [8]: matrix
    Out[8]: 
    [[1, 'a', 'b'],
     [2, 'c', 'd'],
     [1, 'e', 'f'],
     [2, 'g', 'h'],
     [1, 'i', 'j'],
     [2, 'k', 'l']]
    

    As for assigning sections, note that a section is every two rows, which is four letters, so you can use simple floor division to "skip" counts.

    In [9]: sections = {letter:(i//4 + 1) for i,letter in enumerate(letters)}
    
    In [10]: sections
    Out[10]: 
    {'a': 1,
     'b': 1,
     'c': 1,
     'd': 1,
     'e': 2,
     'f': 2,
     'g': 2,
     'h': 2,
     'i': 3,
     'j': 3,
     'k': 3,
     'l': 3}