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 ???
How can I achieve this purpose?
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 ???
if len([node for node in nodelist if node.no == no1]):
print("Found at least one occurence")
|Falseprint( bool( [] ))
|Trueprint( bool( [ 1, 2, 3 ] ))
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 ???
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.
NODE = Node()
NODELIST = []
NODE.NO = 10
NODELIST.append(NODE)
NO1 = 20
if NO1 not in NODELIST[:].NO ???
Dennis Lee Bieber <wlfraed@ix.netcom.com> writes:
if len([node for node in nodelist if node.no == no1]):
print("Found at least one occurence")
I'm not sure you need the "len"; an empty list already is falsy.
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
--
https://mail.python.org/mailman/listinfo/python-list
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 ???
On 23/07/2022 06:28, Khairil Sitanggang wrote:
Hello Expert:
I just started using python. Below is a simple code. I was trying tocheck
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.
On 23/07/2022 06:28, Khairil Sitanggang wrote:
Hello Expert:
I just started using python. Below is a simple code. I was trying tocheck
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.
On 23/07/2022 06:28, Khairil Sitanggang wrote:
Hello Expert:
I just started using python. Below is a simple code. I was trying tocheck
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.
Regarding [Peter Otten's] comment : "
*However, usually object creation and initialization iscombined by allowing arguments to the initializer:*" , so which one of the two classes Node1, Node2 below is more common in practice? Option 2, I guess.
Regarding your comment : "
*However, usually object creation and initialization iscombined by allowing arguments to the initializer:*" , so which one of the two classes Node1, Node2 below is more common in practice? Option 2, I guess.
Thanks,
# option 1:
class Node1:
def __init__(self, a):
self.a = a
self.b = self.calculation()
def calculation(self):
r = self.a + 10
return r
# option 2:
class Node2:
def __init__(self, a, b):
self.a = a
self.b = b
self.b = self.calculation()
def calculation(self):
r = self.a + 10
return r
nd1 = Node1(10)
nd2 = Node2(10, 0) # 0 is dummy, will be overwritten by the call to calculation()
Regarding your comment : "
*However, usually object creation and initialization iscombined by allowing arguments to the initializer:*" , so which one of the two classes Node1, Node2 below is more common in practice? Option 2, I guess.
Thanks,
# option 1:
class Node1:
def __init__(self, a):
self.a = a
self.b = self.calculation()
def calculation(self):
r = self.a + 10
return r
# option 2:
class Node2:
def __init__(self, a, b):
self.a = a
self.b = b
self.b = self.calculation()
def calculation(self):
r = self.a + 10
return r
nd1 = Node1(10)
nd2 = Node2(10, 0) # 0 is dummy, will be overwritten by the call to calculation()
On 25/07/2022 02:47, Khairil Sitanggang wrote:
Regarding your comment : "allowing
*However, usually object creation and initialization iscombined by
arguments to the initializer:*" , so which one of the two classes Node1, Node2 below is more common in practice? Option 2, I guess.
Thanks,
# option 1:
class Node1:
def __init__(self, a):
self.a = a
self.b = self.calculation()
def calculation(self):
r = self.a + 10
return r
# option 2:
class Node2:
def __init__(self, a, b):
self.a = a
self.b = b
self.b = self.calculation()
def calculation(self):
r = self.a + 10
return r
nd1 = Node1(10)
nd2 = Node2(10, 0) # 0 is dummy, will be overwritten by the call to calculation()
An attribute that can be calculated from other attributes should never
be modified through other means. Some day you may want b to become
something else, write, for example,
node = Node2(10, "twenty")
and because by then you have forgotten about the calculation() call end
up with a buggy script. But manually invoking the calculation() method
is also bug prone. You have to remember to repeat it every time you
change a:
node = Node1(10)
assert node.b == 20 # OK
node.a = 20
assert node.b == 30 # fails, a and b are out of sync.
The solution Python has to offer is called "property". Properties in
their simplest form are calculated read-only attributes, i. e. when you
write
print(node.b)
under the hood node.a + 10 is calculated. Here's how to change Node1 to
turn b into such a property:
class Node3a:
def __init__(self, a):
self.a = a
def calculation(self):
return self.a + 10
b = property(calculation)
node = Node3a(42)
print(node.b) # 52
node.a = 1
print(node.b) # 11
Often you are not interested in exposing both the calculation() method
and the property. For cases when you only want to access the property
Python provides a way to define the property with a "decorator":
class Node3b:
def __init__(self, a):
self.a = a
@property
def b(self):
return self.a + 10
When you compare the two classes you can see that I
(1) renamed calculation() to b() and
(2) replaced
def b(self): ...
b = property(b)
with
@property
def b(self): ...
thus avoiding the repetitons of the name.
Are there any disadvantages to properties?
What I presented as an advantage, that the value of the attribute is recalculated every time the attribute is accessed, may sometimes become
a disadvantage, e. g. when it takes a very long time to calculate. In
most cases that should not be a problem, though.
On 23 Jul 2022 22:55:47 GMT, ram@zedat.fu-berlin.de (Stefan Ram) declaimed the following:
Dennis Lee Bieber <wlfraed@ix.netcom.com> writes:
if len([node for node in nodelist if node.no == no1]):
print("Found at least one occurence")
I'm not sure you need the "len"; an empty list already is falsy.
Just wanted to be explicit for the OP.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com
http://wlfraed.microdiversity.freeddns.org/
--
https://mail.python.org/mailman/listinfo/python-list
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 296 |
Nodes: | 16 (2 / 14) |
Uptime: | 44:27:42 |
Calls: | 6,648 |
Files: | 12,197 |
Messages: | 5,329,704 |