简体   繁体   English

如何将符号网格转换为字符串列表

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

the input for the to_strings function is the grid so whatever that the grid shows should be converted into a list of strings where input example: to_strings function 的输入是网格,因此无论网格显示什么,都应转换为字符串列表,其中输入示例:

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

output example: output 示例:

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

first Issue is in this particular function as it does not provide the expected output第一个问题是在这个特定的 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)

I also have an issue with a particular assertion error that needs to be raised where it checks for invalid inputs (the letter x should indicate the row coordinate of the invalid row) where "invalid character in row x" the code shown below is what i came up with however it gives an error我还有一个特定断言错误的问题,需要在它检查无效输入时引发(字母 x 应指示无效行的行坐标),其中“行 x 中的无效字符”下面显示的代码是我的想出了但是它给出了一个错误

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

I need to add an additional optional argument from_strings to the constructor.我需要向构造函数添加一个额外的可选参数from_strings If it's present, this argument must be a list of strings where each string gives a row of the board with the character encoding used in the __str__() method, but without the spaces and the coordinate letters.如果它存在,则此参数必须是一个字符串列表,其中每个字符串给出棋盘的一行,其中字符编码在__str__()方法中使用,但没有空格和坐标字母。

And also a method to_strings(self) that gives a representation of the board as a list of strings in the same format as that accepted by the __init__() method from the from_strings .还有一个to_strings(self)方法,它以字符串列表的形式给出板的表示,其格式与from_strings__init__()方法所接受的格式相同。

How can i get the expected output?我怎样才能得到预期的 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))

for now my code is as such现在我的代码是这样的

however I'm not getting the expected output which is shown below但是我没有得到如下所示的预期 output

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

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

so the output i got is from my code is:所以我从我的代码中得到的 output 是:

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

I executed the code myself and make some changes to get closer to your desired answer.我自己执行了代码并进行了一些更改以更接近您想要的答案。

First,i don't know exactly what this line do, neither what b stands for, so i removed it:首先,我不知道这一行到底是做什么的,也不知道 b 代表什么,所以我删除了它:

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

Then i looked to _str_ method, that is the method that do the class printing, when you call:然后我查看了 _str_ 方法,即执行 class 打印的方法,当您调用时:

print(b)

It doesn't have any mentions to self.from_strings它没有提到self.from_strings

Basically in each line, respecting formatting style for the size the of the grid, it is print the correspondent character of the letter you defined in points dictionary as we can see here:基本上在每一行中,关于网格大小的格式样式,它打印你在点字典中定义的字母的相应字符,我们可以在这里看到:

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

Since the points and grid is like this:由于点和网格是这样的:

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

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

It gives the output:它给出了 output:

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

Assuming that you when from_strings parameter you want that class print that way, i used conditional to use this假设您在 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)

And use the same logic to to_strings method:并对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

The output is shown like this: 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