Python Forum
Syntax to print ndarray member of class containing ndarray
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Syntax to print ndarray member of class containing ndarray
#1
If I define a class Q containing a member which is an ndarray of strings, I can print that class member by name.

If I define another class G containing a member which is an ndarray of class Q objects, what syntax do I use to print all the actual contents of the contained class Q members and not "<__main__.Q object at ....>"?

Python 3 example and output follow.

TIA for any help you can provide to cure my ignorance.

Peter

import numpy as np
class Q:
    def __init__(self,qsize):
        self.qs = qsize
        self.s = np.full([qsize, qsize], " . ", dtype='<U3')


class G:
    def __init__(self, gsize, gval):
        self.gs = gsize
        self.g = np.full([gsize, gsize, gsize], gval, dtype=Q)


qsz = 2
qx = Q(qsz)
print("Created gx = Q()")
print(qsz, qx.qs, qx.s)

gsz = 2
gx = G(gsz, qx)
print("Created gx = G(qx)")
print(gsz, gx.gs, gx.g)
print(gsz, gx.gs, gx.g.s)
Output:

Output:
Created gx = Q() 2 2 [[' . ' ' . '] [' . ' ' . ']] Created gx = G(qx) 2 2 [[[<__main__.Q object at 0x000002538DD74CA0> <__main__.Q object at 0x000002538DD74CA0>] [<__main__.Q object at 0x000002538DD74CA0> <__main__.Q object at 0x000002538DD74CA0>]] [[<__main__.Q object at 0x000002538DD74CA0> <__main__.Q object at 0x000002538DD74CA0>] [<__main__.Q object at 0x000002538DD74CA0> <__main__.Q object at 0x000002538DD74CA0>]]] Traceback (most recent call last): File "clstest.py", line 25, in <module> print(gsz, gx.gs, gx.g.s) AttributeError: 'numpy.ndarray' object has no attribute 's'
Reply
#2
You need to implement __str__ in your class. See, e.g. the docs.
Reply
#3
Implement __str__ in which class, Q or G? In the contained class or the containing class?

Why wouldn't the __str__ method of class Q (or perhaps the one inherited from ndarray?) which obviously works because I can print qx.s also work for gx.g.s?

I guess you are saying that the default __str__ of ndarray does not know how to interpret objects of type ndarray? Why not? It would seem to me a simple case of recursion - "Look there, my elements are my own type, let me invoke myself to interpret them".

Peter
Reply
#4
(Jul-08-2020, 02:10 PM)pjfarley3 Wrote: Implement __str__ in which class, Q or G? In the contained class or the containing class?

In Q if you want a custom string representation of those objects

Quote:Why wouldn't the __str__ method of class Q (or perhaps the one inherited from ndarray?) which obviously works because I can print qx.s also work for gx.g.s?

qx.s is not an instance of Q, is it? It's an instance of ndarray. gx.gs is not an instance of Q either; it's an int. The __str__ method that exists on Q is obviously the one you inherit from object, which is giving you the default string representation that you're seeing. If you print(qx), you'll see the same thing.
Reply
#5
Isn't there some form of list comprehension that can be used as simply as I can print(qx.s) to print(gx.g.s)?

I can obviously set up nested for loops and concatenate formatted strings into an initially null string and finally print the concatenated string, but this seems very un-pythonic.

Isn't there a better way than the following to do thie?

Peter

import numpy as np
class Q:
    def __init__(self,qsize):
        self.qs = qsize
        self.s = np.full([qsize, qsize], " . ", dtype='<U3')


class G:
    def __init__(self, gsize, gval):
        self.gs = gsize
        self.g = np.full([gsize, gsize, gsize], gval, dtype=Q)


qsz = 2
qx = Q(qsz)
print("Created qx = Q()")
print(list(np.shape(qx.s)))
print([x for x in np.shape(qx.s)])
print(qsz, qx.qs, qx.s)

gsz = 2
gx = G(gsz, qx)
print("Created gx = G(qx)")

print(gsz, gx.gs, gx.g)
print("shape(gx.g):", np.shape(gx.g))

pstr = ""
for x in range(gsz):
    for y in range(gsz):
        for z in range(gsz):
            pstr += "{},".format(gx.g[x,y,z].s)
print(pstr)            
Output:
Created qx = Q() [2, 2] [2, 2] 2 2 [[' . ' ' . '] [' . ' ' . ']] Created gx = G(qx) 2 2 [[[<__main__.Q object at 0x000001DB203C10D0> <__main__.Q object at 0x000001DB203C10D0>] [<__main__.Q object at 0x000001DB203C10D0> <__main__.Q object at 0x000001DB203C10D0>]] [[<__main__.Q object at 0x000001DB203C10D0> <__main__.Q object at 0x000001DB203C10D0>] [<__main__.Q object at 0x000001DB203C10D0> <__main__.Q object at 0x000001DB203C10D0>]]] shape(gx.g): (2, 2, 2) [[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],[[' . ' ' . '] [' . ' ' . ']],

(Jul-09-2020, 04:58 AM)ndc85430 Wrote:
(Jul-08-2020, 02:10 PM)pjfarley3 Wrote: Implement __str__ in which class, Q or G? In the contained class or the containing class?

In Q if you want a custom string representation of those objects

Quote:Why wouldn't the __str__ method of class Q (or perhaps the one inherited from ndarray?) which obviously works because I can print qx.s also work for gx.g.s?

qx.s is not an instance of Q, is it? It's an instance of ndarray. gx.gs is not an instance of Q either; it's an int. The __str__ method that exists on Q is obviously the one you inherit from object, which is giving you the default string representation that you're seeing. If you print(qx), you'll see the same thing.

Thanks for that reply, and I do understand that asking to print an entire Q object as a whole requires a __str__ method in Q. But I am only asking to print the "s" components of the ndarray of Q objects gx.g, or in my naive way gx.g[].s or some equivalent syntax.

Shouldn't the s component of the ndarray of Q objects be printable in some simple manner not involving for loops?

Peter
Reply
#6
(Jul-09-2020, 05:16 AM)pjfarley3 Wrote: Isn't there some form of list comprehension that can be used as simply as I can print(qx.s) to print(gx.g.s)?

Quote:But I am only asking to print the "s" components of the ndarray of Q objects gx.g, or in my naive way gx.g[].s or some equivalent syntax.

Remember that ndarray objects can contain objects of basically any other type, so it's up to the programmer to know what type is in them and how to deal with them. Therefore, you have to go over all of the items and do your printing as you are, or transform the ndarray of Qs into an ndarray of whatever type Q.s is. With Python lists, you'd use map or, like you say, a list comprehension to do that transformation, but I don't know the API for ndarray well enough to know which method to use (there doesn't seem to be a map).
Reply
#7
(Jul-09-2020, 05:37 AM)ndc85430 Wrote: Remember that ndarray objects can contain objects of basically any other type, so it's up to the programmer to know what type is in them and how to deal with them. Therefore, you have to go over all of the items and do your printing as you are, or transform the ndarray of Qs into an ndarray of whatever type Q.s is. With Python lists, you'd use map or, like you say, a list comprehension to do that transformation, but I don't know the API for ndarray well enough to know which method to use (there doesn't seem to be a map).

Thanks for the advice. I'm going to have to chew on that for a while and do some more RTFM. I discovered numpy.nditer for iterating over an ndarray, but there are issues specifying just the Q.s member of each element of the gx.g ndarray while ignoring the Q.qs member.

I'll reply again after I do more research.

Peter
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Class member become static Quasar999 1 643 Sep-16-2023, 12:52 PM
Last Post: deanhystad
  print(data) is suddenly invalid syntax db042190 6 1,119 Jun-14-2023, 02:55 PM
Last Post: deanhystad
  AttributeError: 'numpy.ndarray' object has no attribute 'load' hobbyist 8 6,967 Jul-06-2022, 10:55 AM
Last Post: deanhystad
  labels.append(self.classes.index(member.find('name').text)) hobbyist 1 1,873 Dec-15-2021, 01:53 PM
Last Post: deanhystad
  invalid syntax in my class CompleteNewb 2 1,844 Dec-13-2021, 09:39 AM
Last Post: Larz60+
  Tuple generator, and function/class syntax quazirfan 3 3,761 Aug-10-2021, 09:32 AM
Last Post: buran
  How can I pass&return ndarray between python and c++? JESuh 0 1,738 Mar-09-2021, 08:29 AM
Last Post: JESuh
  How to define a variable in Python that points to or is a reference to a list member JeffDelmas 4 2,594 Feb-28-2021, 10:38 PM
Last Post: JeffDelmas
  Invalid syntax on print function DoctorSmiles 2 2,769 Jul-12-2020, 07:39 PM
Last Post: DoctorSmiles
  Function to return list of all the INDEX values of a defined ndarray? pjfarley3 2 1,918 Jul-10-2020, 04:51 AM
Last Post: pjfarley3

Forum Jump:

User Panel Messages

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