Posts: 66
Threads: 19
Joined: Nov 2018
Dec-18-2018, 04:11 PM
(This post was last modified: Dec-18-2018, 04:12 PM by dan789.)
Hi all, I´m trying to make a method __str__ for my class. It should have just one line (return ...) as usually this method is supposed to look like, and it should create a string from two dimensional list. List contains 9 lines, each with 9 items (items can be "." or number 1-9) separated by a space. What do I have so far is this:
def __str__(self):
my_str = ""
for line in self.tab:
for item in range(len(line)):
my_str += str(line[item]) + " "
my_str += "\n"
return my_str As you can see, this takes many lines, but it should be just in one. Can you help me with that? Thanks.
Posts: 443
Threads: 1
Joined: Sep 2018
Dec-18-2018, 04:55 PM
(This post was last modified: Dec-18-2018, 04:55 PM by stullis.)
def __str__(self):
return "\n".join([" ".join(x) for x in self.tab])
Posts: 4,804
Threads: 77
Joined: Jan 2018
Dec-18-2018, 05:39 PM
(This post was last modified: Dec-18-2018, 06:32 PM by Gribouillis.)
dan789 Wrote:it should have just one line (return ...) as usually this method is supposed to look like There is no special rule concerning the __str__() method. It is supposed to return a str instance but it can be 20000 lines long if you want (yes I tested this).
Posts: 66
Threads: 19
Joined: Nov 2018
@ stullis seems like it could work, but there is a problem with integers in a list. Numbers 1-9 are integers, not strings, what means that this generator notation doesn´t work there.
@ Gribouillis I thought so, but if there is a way how to make this method 1 line, I prefer it.
Posts: 8,169
Threads: 160
Joined: Sep 2016
Dec-18-2018, 07:32 PM
(This post was last modified: Dec-18-2018, 07:33 PM by buran.)
(Dec-18-2018, 07:17 PM)dan789 Wrote: if there is a way how to make this method 1 line, I prefer it. can you give an example as it's not very clear (i.e. input and desired output) e.g. list contains lines?
Posts: 66
Threads: 19
Joined: Nov 2018
This is the content of two dimensional list:
[['.', '.', '.', '.', '.', 9, '.', '.', '.'], ['.', '.', 7, '.', 8, 6, '.', '.', '.'], [6, '.', '.', 3, '.', '.', '.', '.', '.'], ['.', 4, '.', '.', '.', 7, '.', '.', 8], ['.', '.', '.', '.', '.', '.', '.', 3, 2], ['.', '.', 3, 6, '.', 5, 1, '.', '.'], ['.', 6, '.', 7, '.', '.', '.', 8, '.'], [3, '.', 2, '.', '.', '.', 4, 9, '.'], ['.', 5, 4, 8, '.', '.', '.', '.', 3]] What do I want to get is:
. . . . . 9 . . .
. . 7 . 8 6 . . .
6 . . 3 . . . . .
. 4 . . . 7 . . 8
. . . . . . . 3 2
. . 3 6 . 5 1 . .
. 6 . 7 . . . 8 .
3 . 2 . . . 4 9 .
. 5 4 8 . . . . 3
Posts: 8,169
Threads: 160
Joined: Sep 2016
Dec-18-2018, 08:15 PM
(This post was last modified: Dec-18-2018, 08:22 PM by buran.)
what @ stullis suggested with small amendment
def __str__(self):
return "\n".join([" ".join(map(str, sub_list)) for sub_list in self.tab])
Posts: 66
Threads: 19
Joined: Nov 2018
Dec-18-2018, 08:37 PM
(This post was last modified: Dec-18-2018, 08:37 PM by dan789.)
Well, this works, thanks. :)
But now I need to create a copy of this list, since I need to call this method later again, after some other methods change self.tab, but I want __str__() to return still the same list. I tried to make a copy of self.tab using "self.tab.copy()" into new variable and this used in __str__(). But whenever I call __str__() after something changed in self.tab, it also changes in self.tab_copy. How to deal with that?
I simply added into __init__ new variable self.tab_copy and in __str__() changed to "return "\n".join([" ".join(map(str, x)) for x in self.tab_copy])", but is still changes the inital self.tab (as I described above).
Posts: 4,804
Threads: 77
Joined: Jan 2018
Dec-18-2018, 08:44 PM
(This post was last modified: Dec-18-2018, 08:51 PM by Gribouillis.)
I have a longer solution, but as your data resembles a Sudoku board, I think it might be interesting
allbox = u''.join(chr(9472 + x) for x in range(200))
box = [ allbox[i] for i in (2, 0, 12, 16, 20, 24, 44, 52, 28, 36, 60) ]
(vbar, hbar, ul, ur, ll, lr, nt, st, wt, et, plus) = box
hh = hbar * 7
nl = '\n'
topline = ul + (hh + nt) * 2 + hh + ur
midline = wt + (hh + plus) * 2 + hh + et
botline = ll + (hh + st) * 2 + hh + lr
def to_str(board):
result = [topline + nl]
for i, z in zip(range(0, 9, 3), (midline + nl, midline + nl, botline)):
for row in board[i:i+3]:
result.append(
vbar + vbar.join(
' ' + ' '.join(str(k) for k in row[j:j+3]) + ' ' for j in range(0, 9, 3)) + vbar + nl)
result.append(z)
return ''.join(result)
if __name__ == '__main__':
data = [
['.', '.', '.', '.', '.', 9, '.', '.', '.'],
['.', '.', 7, '.', 8, 6, '.', '.', '.'],
[6, '.', '.', 3, '.', '.', '.', '.', '.'],
['.', 4, '.', '.', '.', 7, '.', '.', 8],
['.', '.', '.', '.', '.', '.', '.', 3, 2],
['.', '.', 3, 6, '.', 5, 1, '.', '.'],
['.', 6, '.', 7, '.', '.', '.', 8, '.'],
[3, '.', 2, '.', '.', '.', 4, 9, '.'],
['.', 5, 4, 8, '.', '.', '.', '.', 3]]
print(to_str(data)) Output: ┌───────┬───────┬───────┐
│ . . . │ . . 9 │ . . . │
│ . . 7 │ . 8 6 │ . . . │
│ 6 . . │ 3 . . │ . . . │
├───────┼───────┼───────┤
│ . 4 . │ . . 7 │ . . 8 │
│ . . . │ . . . │ . 3 2 │
│ . . 3 │ 6 . 5 │ 1 . . │
├───────┼───────┼───────┤
│ . 6 . │ 7 . . │ . 8 . │
│ 3 . 2 │ . . . │ 4 9 . │
│ . 5 4 │ 8 . . │ . . 3 │
└───────┴───────┴───────┘
Posts: 3,458
Threads: 101
Joined: Sep 2016
(Dec-18-2018, 08:37 PM)dan789 Wrote: But now I need to create a copy of this list, since I need to call this method later again You should be able to call str(the_object) an infinite number of times, and not have any data change. If you're copying lists inside the __str__ function, you're doing something horribly wrong. Please, share some code, instead of giving tiny little glimpses of what might be lurking under the surface of your code.
|