Object in List : how?

Peter Otten __peter__ at web.de
Sun Jul 24 03:19:45 EDT 2022


On 23/07/2022 06: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

This just overwrites the attribute; the previous value 10 is lost.

> NODELIST.append(NODE)
>
> NODE.NO = 30

This againoverwrites the attribute; the previous value 20 is lost.

> NODELIST.append(NODE)


You are three times appending the *same* node to the list.
To create a new node you need to invoke the initializer:

[I'm following a common convention and use lowercase names in my examples]

nodelist = []

# first node
node = Node()
node.no = 10
nodelist.append(node)

# second node
node = Node()  # this is crucial
node.no = 20
nodelist.append(node)

... and so on. However, usually object creation and initialization is
combined by allowing arguments to the initializer:

class Node:
     def __init__(self, no, a):
         self.no = no
         self.a = a

nodelist = []
for no in [10, 20, 30]:
     nodelist.append(Node(no, 20))

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

You are checking if the list contains an item with a specific attribute
value, so you cannot use the nodelist directly, you need an intermediate
list that contains the attribute values:

no1 = 20
nos = [node.no for node in nodelist]
if no1 not in nos:
     print("not found")

There's one disadvantage to this approach. If the node list is huge
another huge list with the attribute values is built even though the
first item in the nodelist may already have the searched-for attribute
value. To avoid the overhead you could write a function:

def contains_no(nodes, no):
     for node in nodes:
         if node.no == no:
             return True
     return False

if not contains_no(nodelist, 20):
     print("not found")

But Python has something more elegant, a kind of /lazy/ /list/ called
"generator expression" where each item is calculated on demand. With
that you can write

if 20 not in (node.no for node in nodelist):
     print("not found")

and your script will stop inspecting further nodes as soon as a matching
node is found.


More information about the Python-list mailing list