Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Magic method __str__
#1
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.
Reply
#2
def __str__(self):
    return "\n".join([" ".join(x) for x in self.tab])
Reply
#3
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).
Reply
#4
@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.
Reply
#5
(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?
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#6
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
Reply
#7
what @stullis suggested with small amendment
def __str__(self):
    return "\n".join([" ".join(map(str, sub_list)) for sub_list in self.tab])
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#8
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).
Reply
#9
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 │ └───────┴───────┴───────┘
Reply
#10
(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.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  magic related field in Django model sonh 1 1,244 Apr-24-2022, 12:37 PM
Last Post: sonh
  Need a little help with numpy array magic. pmf71 0 1,158 Dec-01-2021, 02:51 AM
Last Post: pmf71
  TypeError: __str__ returned non-string (type tuple) Anldra12 1 7,418 Apr-13-2021, 07:50 AM
Last Post: Anldra12
  Magic Method Arithmetic Operators ClownPrinceOfCrime 3 2,330 Jan-10-2021, 03:24 PM
Last Post: ndc85430
  How to eliminate magic squares formed by the same numbers, but permuted frame 7 3,643 May-09-2019, 11:28 AM
Last Post: frame
  TypeError: __str__ returned non-string error jolinchewjb 5 10,114 Jan-24-2019, 07:54 AM
Last Post: jolinchewjb
  [split] Bad magic number. What is it ? Douglas 2 5,279 Oct-22-2018, 10:38 AM
Last Post: Douglas
  How to add metakernel magic for python rikaki__ 0 2,027 Jul-04-2018, 02:49 AM
Last Post: rikaki__
  Bad magic number. What is it ? sylas 4 7,817 Sep-20-2017, 05:52 PM
Last Post: sylas
  How to Create Very Very Special Class with too many magic methods ? harun2525 5 4,380 Apr-13-2017, 10:18 PM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020