Store and Retrieve Objects from Python Lists - python

I am new to python and have a difficulty getting an object to be stored and access in an array or a list in Python.
I've tried doing something like this:
class NodeInfo:
def __init__(self, left, value, right):
self.l = left
self.r = right
self.v = value
tree[0] = NodeInfo(0,1,2)
tree[0].l = 5
tree[0].r = 6
tree[0].v = 7
When I try to assign values to or try to read from the variable, I get the following error:
tree[0] = NodeInfo(0,1,2)
NameError: name 'tree' is not defined
What am I doing wrong, or is there a different way to assign and read objects from arrays or lists in Python.

You need to create list first and use append method to add an element to the end of it.
tree = []
tree.append(NodeInfo(0,1,2))
# or
tree = [NodeInfo(0,1,2)]

Related

Assign a different index to variable over the function

I am having trouble assigning different indexes to variables over a function in python. For example, if i have coordinates for points in 3D space and want to assign a name to a variable in a function, lets say "point_1", how do i do that?
Looking at this code:
side_1_point = (1.0,1.0,15.0)
side_1_face = boxPart.faces.findAt((side_1_point,))
side_1_region = regionToolset.Region(faces=(side_1_face))
side_2_point = (17.0,1.0,15.0)
side_2_face = boxPart.faces.findAt((side_2_point,))
side_2_region = regionToolset.Region(faces=(side_2_face))
side_3_point = (18.0,1.0,14.0)
side_3_face = boxPart.faces.findAt((side_3_point,))
side_3_region = regionToolset.Region(faces=(side_3_face))
How can i define a function as:
def assign_face(coord1,coord2,coord3,index)
side_(index)_face = boxPart.faces.findAt((coord1,coord2,coord3,))
return side_(index)_face
I am struggling to find the right syntax.
Thank you

Error when appending to python object lists

I have defined a series of python objects of class dofiles which have a name and some empty lists.
class dofile:
name = ""
lines = []
inputs = []
outputs = []
intermediates = []
I am using the following code to loop through a list of these dofile objects called dofiles (after I have run code which fills up the lines list for each object which I know works correctly). The problematic code detects the phrase using and the word after it, then should append the word to the inputs list for each object.
for dofile in dofiles:
for line in dofile.lines:
# using
using_tups = re.findall(r'(using)\s([^\s,]+)', line)
for tuple in using_tups:
dofile.inputs.append(tuple[1])
However, I am ending up with the word appended to the inputs list of all of the dofile objects in dofiles. (ex: print(dofiles[0].inputs) and print(dofiles[1].inputs) return the same thing although they scan different files).
Am I missing something about how objects, lists, or loops work in Python?
I've tried (dofile.inputs).append(tuple[1]) but it doesn't seem to make a difference.
Thanks.
You're creating static vars, variables that are consistent across all dofile class instances. Essentially what is going on is that instead of having an "inputs" list for all dofile instances, you have one list that each one points to. To make them specific to a single instance, initialize them inside the __init__ class:
class dofile:
def __init__(self):
self.name = ""
self.lines = []
self.inputs = []
self.outputs = []
self.intermediates = []

How can I use the value of a variable in the name of another without using a dictionary in python?

The answer people have already given for using the value of a variable in the assignment of another is:
to create a dictionary and,
use dict[oldVariable] instead of defining a new one
I don't think that works in the context of what I'm trying to do...
I'm trying to define a class for a vector which would take a list as an input and assign an entry in the vector for each element of the list.
My code looks something like this right now:
class vector:
def __init__(self, entries):
for dim in range(len(entries)):
for entry in entries:
self.dim = entry #here I want to assign self.1, self.2, etc all the way to however
#many elements are in entries, but I can't replace self.dim with
# dict[dim]
def __str__(self):
string = []
for entry in range(1,4):
string.append(self.entry)
print(string)
How do I do this?
What you are doing here is a bit strange, since you are using a variable named "dim" in a for, but you do not do anything with that variable. It looks like you want to use a class as if it was an array... why don't you define an array within the class and access it from the outside with the index? v.elements[1] ... and so on?
Example:
class Vector:
def __init__(self, entries):
self.elements = []
for e in entries:
self.elements.append(self.process(e))
def __str__(self):
buff = ''
for e in self.elements:
buff += str(e)
return buff
Hope this helps.
If I'm reading your question correctly, I think you're looking for the setattr function (https://docs.python.org/2/library/functions.html#setattr).
If you wanted to name the fields with a particular string value, you could just do this:
class vector:
def __init__(self, entries):
for dim in range(len(entries)):
for entry in entries:
#self.dim = entry
setattr(self, str(dict[dim]), dim)
That will result in your object self having attributes named with whatever the values of dict[dim] are and values equal to the dim.
That being said, be aware that an integer value is generally a poor attribute name. You won't be able to do print obj.1 without error. You'd have to do getattr(obj,'1').
I agree with #Ricardo that you are going about this strangely and you should probably rethink how you're structuring this class, but I wanted to directly answer the question in case others land here looking for how to do dynamic naming.

What does this class do?-Python

I am trying to understand what does this class
class undo:
def __init__(self, ss):
self.ss = ss
In my head it should simply put the value of ss uniquely in the variables i decide to use,but when I'm using it it rewrites all the variables, as if it was shared.
sum_expenses[100][0] = 100
sum_expenses[99][2] = 99
s = 1
a = [0 for i in range(100)]
a[s] = undo(sum_expenses)
output(a[1].ss)
sum_expenses[100][0] = 0
b = undo(sum_expenses)
print " "
print b.ss
print " "
sum_expenses[99][2] = 1
a[2] = undo(sum_expenses)
print a[2].ss
I do not understand why it overwrites all the variables with the current values of sum_expense, when I try to put it individually so that I can use the past values of sum_expenses.
Thank you and have a good day!
It happens because you're giving __init__ a reference to the list. If you change the list somewhere else, the reference in .ss still points to the same list, so the changes are visible there, too.
You could copy the list, since it's 2D try deepcopy.
Everytime you call this function it overrides reference to thr whole array ss, changing it to the new one you just passed to the constructor.
You can also create this array within the class and pass indexes and value to it like so:
undo.add(index1,index2,value)
Or you can make another variable ss_old and have make the function return that variable before you set it to a new value.

list of objects containing lists of objects

I'm trying to create a list of objects (Elements), where each element contains a list of objects (GaussPoints). The number of GaussPoints per Element can be variable, although in the example below each element has only one GaussPoint for simplicity.
class Element:
gp = []
class GaussPoint:
argument = 0
k = 0
elements = []
for ele in xrange(4):
k = k+1
anEle = Element()
aGP = GaussPoint()
aGP.argument = k
print k
elements.append(anEle)
elements[ele].gp.append(aGP)
print "testing the data structure:"
for ele in xrange(4):
print elements[ele].gp[0].argument
The output is:
1
2
3
4
testing the data structure:
1
1
1
1
What I'm expecting would be:
1
2
3
4
testing the data structure:
1
2
3
4
Somehow the code doesn't create a new list of GaussPoints for each Element, but appends to the same one.
I'm obviously misunderstanding something quite fundamental about Python. Could anyone please help?
You need to make Element.gp an instance variable, like so:
class Element:
def __init__(self):
self.gp = []
Currently, gp is a member of the class itself and is in effect shared by all instances of the class. You change it in one, and it appears to change in all.
It is arguably good style to make the same change to GaussPoint.argument:
class GaussPoint:
def __init__(self):
self.argument = 0
Finally, I'd recommend reading the tutorial on classes.
You're initializing Element.gp as a class variable, rather than an instance variable, so it's shared across all your Element objects. You end up with 1 gp being an array of length 4, rather than 4 gps of length 1.
Instead, initialize it in an __init__ method like so:
class Element:
def __init__(self):
self.gp = []
You're making argument a class variable, but since you reassign it for each instance, rather than modify it as you do element, it ends up holding the value you'd expect.

Categories

Resources