簡體   English   中英

如何將符號網格轉換為字符串列表

[英]How can I convert the grid of symbols into a list of strings

to_strings function 的輸入是網格,因此無論網格顯示什么,都應轉換為字符串列表,其中輸入示例:

   A B C
 1 . . .
 2 . @ .
 3 . O .

output 示例:

['...', '.@.', '.O.']
True

第一個問題是在這個特定的 function 中,因為它沒有提供預期的 output

    def to_strings(self):
        from itertools import chain

        m_list_tostring=[]
        for i in range(len(self.grid)):
            x=list(chain.from_iterable(self.grid))
            m_list_tostring = ''.join([str(x) for self.grid, i in enumerate(x)])  # to convert the list of characters into a string
        print(x)

    return str(x)

我還有一個特定斷言錯誤的問題,需要在它檢查無效輸入時引發(字母 x 應指示無效行的行坐標),其中“行 x 中的無效字符”下面顯示的代碼是我的想出了但是它給出了一個錯誤

assert i == self.grid[i], "invalid character in row "+i

我需要向構造函數添加一個額外的可選參數from_strings 如果它存在,則此參數必須是一個字符串列表,其中每個字符串給出棋盤的一行,其中字符編碼在__str__()方法中使用,但沒有空格和坐標字母。

還有一個to_strings(self)方法,它以字符串列表的形式給出板的表示,其格式與from_strings__init__()方法所接受的格式相同。

我怎樣才能得到預期的 output?

from string import ascii_uppercase as letters
class Board:
#Dictionary created for the colours and the respected symbols
    points = {'E': '.', 'B': '@', 'W': 'O'}
#Constructor
    def __init__(self,size=19,from_strings=None):
        assert 2 <= size <= 26, "Illegal board size: must be between 2 and 26."
        assert type(from_strings) is list,"input is not a list"
        assert len(from_strings)==size, "length of input list does not match size"
        for i in from_strings:
            assert type(i)==str, "row "+i+" is not a string"
            assert len(i)==size,"length of row "+i+" does not match size"
            #assert i== b[i], "invalid character in row "+i
        self.size = size
        self.grid = [['E'] * size for _ in range(size)]
        self.from_strings = [] if from_strings is None else from_strings
       def get_size(self): #Returns the size of the grid created by the constructor
        return self.size

    def __str__(self): #creating the grid
        padding=' ' #Creating a variable with a space assigned so that it acts as a padding to the rows that have a single digit
        heading = '   ' + ' '.join(letters[:self.size]) #Alphabetical heading is created
        lines = [heading] #adding the alphabetical heading into a list named lines to which the rows will be added later
        for r, row in enumerate(self.grid):
            if len(self.grid)<10: #for the grid with a size less than 10 to add the space to the start of the row for the single digits to be aligned
                line = " " +f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
                lines.append(line)
            else: #for the grids that are larger than 9
                if r>9: #for rows 1 to 9 the single digits are aligned according to the first digit from the right of the two digit rows
                    line =f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
                    line=padding+line #adding the space using the variable padding to the row created
                    lines.append(line) #adding the row to the list of rows
                else: #for the rows 10 onwards - as there is no requirement to add a padding it is not added here
                    line = f'{self.size - r} ' + ' '.join(self.points[x] for x in row)#creation of the row
                    lines.append(line) #adding the newly created row to the list of rows
        return '\n'.join(lines)


    def _to_row_and_column(self, coords):
        # destructure coordinates like "B2" to "B" and 2
        alpha, num = coords
        colnum = ord(alpha) - ord('A') + 1
        rownum = self.size - int(num) + 1
        assert 1 <= rownum <= self.size,"row out of range"
        assert 1 <= colnum <= self.size,'column out of range'
        return rownum, colnum

    def set_colour(self, coords, colour_name):
        rownum, colnum = self._to_row_and_column(coords)
        assert len(coords)==2 or len(coords)==3, "invalid coordinates"
        assert colour_name in self.points,"invalid colour name"
        self.grid[rownum - 1][colnum - 1] = colour_name

    def get_colour(self, coords):
        rownum, colnum = self._to_row_and_column(coords)
        return self.grid[rownum - 1][colnum - 1]

    def to_strings(self):
        from itertools import chain
        m_list_tostring=[]
        for i in range(len(self.grid)):
            x=list(chain.from_iterable(self.grid))
            m_list_tostring = ''.join([str(x) for self.grid, i in enumerate(x)])  # to convert the list of characters into a string
            print(x)
        
        return x

b =Board(3, ["O.O", ".@.", "@O."])
print(b)
print(b.to_strings())
c =Board(b.get_size(), b.to_strings())
print(str(b) == str(c))

現在我的代碼是這樣的

但是我沒有得到如下所示的預期 output

   A B C
 3 O . O
 2 . @ .
 1 @ O .

['O.O', '.@.', '@O.']
True

所以我從我的代碼中得到的 output 是:

['E', 'E', 'E', 'E', 'E', 'E', 'E', 'W', 'E']

我自己執行了代碼並進行了一些更改以更接近您想要的答案。

首先,我不知道這一行到底是做什么的,也不知道 b 代表什么,所以我刪除了它:

assert i== b[i], "invalid character in row "+i .

然后我查看了 _str_ 方法,即執行 class 打印的方法,當您調用時:

print(b)

它沒有提到self.from_strings

基本上在每一行中,關於網格大小的格式樣式,它打印你在點字典中定義的字母的相應字符,我們可以在這里看到:

join(self.points[x] for x in row)

由於點和網格是這樣的:

self.grid = [['E'] * size for _ in range(size)]

points = {'E': '.', 'B': '@', 'W': 'O'}

它給出了 output:

   A B C
 3 . . .
 2 . . .
 1 . . .

假設您在 from_strings 參數時希望 class 以這種方式打印,我使用條件來使用它

    def __str__(self): #creating the grid
            padding=' ' #Creating a variable with a space assigned so that it acts as a padding to the rows that have a single digit
            heading = '   ' + ' '.join(letters[:self.size]) #Alphabetical heading is created
            lines = [heading] #adding the alphabetical heading into a list named lines to which the rows will be added later
            for r, row in enumerate(self.grid):
                if len(self.grid)<10: #for the grid with a size less than 10 to add the space to the start of the row for the single digits to be aligned
                    if (self.from_strings):
                        line = " " +f'{self.size - r} ' + ' '.join(self.from_strings[r])
                    else: 
                        line = " " +f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
                    lines.append(line)
                else: #for the grids that are larger than 9
                    if r>9: #for rows 1 to 9 the single digits are aligned according to the first digit from the right of the two digit rows
                        if (self.from_strings):
                            line = f'{self.size - r} ' + ' '.join(self.from_strings[r])
                        else:
                            line =f'{self.size - r} ' + ' '.join(self.points[x] for x in row)
                        line=padding+line #adding the space using the variable padding to the row created
                        lines.append(line) #adding the row to the list of rows
                    else: #for the rows 10 onwards - as there is no requirement to add a padding it is not added here
                        if (self.from_strings):
                            line = f'{self.size - r} ' + ' '.join(self.from_strings[r])
                        else: 
                            line = f'{self.size - r} ' + ' '.join(self.points[x] for x in row)#creation of the row
                        lines.append(line) #adding the newly created row to the list of rows
            return '\n'.join(lines)

並對to_strings方法使用相同的邏輯:

    def to_strings(self):
        padding=' '
        lines = [] 
        for r, row in enumerate(self.grid):
            if self.from_strings : 
                lines.append(''.join(self.from_strings[r]))
            else :
                lines.append(''.join(self.points[x] for x in row))
        return lines

output是這樣顯示的:

   A B C
 3 O . O
 2 . @ .
 1 @ O .
['O.O', '.@.', '@O.']
True

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM