Object in List : how?

dn PythonList at DancesWithMice.info
Sat Jul 23 19:52:45 EDT 2022


On 24/07/2022 09.57, MRAB wrote:
> On 23/07/2022 05:28, Khairil Sitanggang wrote:
>> Hello Expert:
>>
>> I just started using python. Below is a simple code.  I was trying to
>> check
>> if, say, NO1 is not in the NODELIST[:].NO
>> How can I achieve this purpose?
>>
>> Regards,
>> -Irfan
>>
>>
>> class Node:
>>      def __init__(self):
>>          self.NO = 0
>>          self.A = 20
>>
>> NODE = Node()
>> NODELIST = []
>>
>> NODE.NO = 10
>> NODELIST.append(NODE)
>>
>> NODE.NO = 20
>> NODELIST.append(NODE)
>>
>> NODE.NO = 30
>> NODELIST.append(NODE)
>>
>>
>> NO1 = 20
>> if NO1 not in NODELIST[:].NO  ???
> 
> No, you can't do it that way. You have to iterate through the list and
> check each member individually:
> 
>     if any(NO1 == N.NO for N in NODELIST):
> 
> And another thing: you've created only 1 node, and you're changing it
> each time before adding it to the list, so the list ends up with 3
> references to the _same_ object.

+1


Imagine the object (Node) was instead a person, and a bunch of us-people
get together in a room. You could shout (above the polite conversation)
"is Fred here?" and Fred will reply - or if Fred is elsewhere, silence
will reign. That works - but only because everyone knows their own name.

Now imagine something like (my) grade school, where the teacher takes a
roll/register to note who is present for (or absent from) class. In this
case another staff-member could enter the room and instead of shouting
(which would be rude), can ask the teacher "is Fred here?". The teacher
is able to answer from the roll.

The former case is (sort of) the solution proposed above - in looking
for Fred, you walk through the room, asking each person in-turn "are you
Fred?".

The latter is the case for Node and what you were hoping to implement.

Thus, an alternate approach is to keep a register of nodes. Note that
this is more than a list, because each element of the list (each node)
is also identified (on the list) by its name. So, two pieces of
(related) data: the id of the node, and the node itself - the name of
the person and the person him-/her-self.

Assuming you only have one ID that will be used to access a node,
Python's built-in dict[ionary] data-structure will provide the advantage
of direct-access (instead of going through (on average) half the nodes,
asking each one in-turn, are you ...

So:

> NODE = Node()
> NODELIST = []
> 
> NODE.NO = 10
> NODELIST.append(NODE)

becomes:

    graph = dict{}	# could be written as: graph = {}
    node10 = Node( 10 )
    graph[ node.id ] = node10

or even:

    graph[ 20 ] = Node( 20 )

if you don't need lots of nodes 'hanging around' outside of the 'list'
(actually a dict) representing the graph.


Then:

> NO1 = 20
> if NO1 not in NODELIST[:].NO  ???

becomes a single line:

    the_node_required = graph[ 20 ]

where "20" is the search-criteria.

Does that make sense?


If it does, and when you realise that you'd like to do more with the
graph than retrieve single nodes (and more-importantly, should you want
(or dare) to delve further into the depths of Object-Oriented
Programming) you could declare a second class (graph) containing a
number of "methods". If one of the methods implemented is __contains__()
then you could indeed ask:

    if 20 in graph:

ie "is Fred in-class today?"
but just as we would ask "is Fred here?" rather than "is someone
identified by the name 'Fred' here?", it would seem better form to write:

    if node( 20 ) in graph:

ie is there a node with the id of 20, somewhere within the graph?


Such might involve sub-classing OrderedDict, UserDict, or even UserList,
from the Collections library in the (provided/"batteries-included")
Python Standard Library: https://docs.python.org/3/library/collections.html

If needed, the extra methods you choose to implement might include such
functionality as connecting nodes 10 and 20 with a path/edge, being able
to traverse edges, and so-on...

Thus, we've covered two categories of class/object: one, a 'data-class'
which contains data about a single node; the other a 'collection-class'
which contains multiple nodes making-up the graph. A useful distinction
and a common related-pair of data-constructs!
-- 
Regards,
=dn


More information about the Python-list mailing list