How can i duplicate a list of lists (or any other types) in a way that the resulting lists are new objects and not references to the old ones? As an example i have the following list of lists:
l=[[1,2],[3,4]]
what i want as result is:
l=[[1,2],[3,4],[1,2],[3,4]]
If i do l*=2 the new sub-lists are references to the old sub-lists.
Doing l[0].append("python") will result in
l=[[1,2,'python'],[3,4],[1,2,'python'],[3,4]]
Also creating a new list like:
l2=list(l)
or
l2=l[:]
doesn't solve the problem. I want to have new sub-lists which are independent of their origin and which upon changing have no impact on their old fellows. How can i do this i python?
In general, the best way to copy a nested data structure so that copies get made of all the references (not just the ones at the top level) is to use copy.deepcopy. In your nested list example, you can do:
l.extend(copy.deepcopy(l))
deepcopy will still work even if the data structure contains references to itself, or multiple references to the same object. It usually works for objects stored as attributes on an instances of custom classes too. You can define a __deepcopy__ method if you want to give a class special copying behavior (e.g. if some of its attributes are bookkeeping data that shouldn't be copied).
Here's a version of your nested list example code using instances of a linked list class rather than Python lists. copy.deepcopy does the right thing!
class linked_list(object):
def __init__(self, value, next=None):
self.value = value
self.next = next
def __repr__(self):
if self.next is not None:
return "({!r})->{!r}".format(self.value, self.next)
else:
return "({!r})".format self.value
lst = linked_list(linked_list(1, linked_list(2)),
linked_list(linked_list(3, linked_list(4))))
print(lst) # prints ((1)->(2))->((3)->(4))
lst.next.next = copy.deepcopy(lst)
print(lst) # prints ((1)->(2))->((3)->(4))->((1)->(2))->((3)->(4))
lst.value.value = 5
print(lst) # prints ((5)->(2))->((3)->(4))->((1)->(2))->((3)->(4))
Related
The problem is basically after I call a function with a list that list changes content even though I'm using list + [something] which should return a new reference to a new list not the same as list.
example code:
def foo(a):
#modifying the list using del and remove
def bar(b):
alist = b
foo(alist + [something])
#at this point alist != the original alist
I also tried making a tmp list using list(alist) and alist + [something]
Can I use pastebin here to refer to the actual code?
I guess your list alist contains some sublists in it. In this case, even if you do alist + [something], you are still passing the pointers to those sublists to function foo().
There is a hard and quick solution to that, simply use python's deepcopy() function as follows. This will make a replication of everything in your list in the memory.
from copy import deepcopy
def bar(b):
b_copy = deepcopy(b)
foo(b_copy)
This may appear like a very trivial question but I have just started learning python classes and objects. I have a code like below.
class Point(object):
def __init__(self,x,y):
self.x = float(x)
self.y = float(y)
def __str__(self):
return '('+str(self.x)+','+str(self.y)+')'
def main():
p1 = Point(pt1,pt2)
p2 = Point(pt3,pt4)
p3 = Point(pt5,pt6)
p4 = Point(pt7,pt8)
parray = [p1,p2,p3,p4]
print " Points are", p1,p2,p3,p4
print "parray",parray
I m getting the below Output :
Points are (4.0,2.0) (4.0,8.0) (4.0,-1.0) (100.0,1.0)
parray - intersection.Point object at 0x7ff09f00a550, intersection.Point object at 0x7ff09f00a410, intersection.Point object at 0x7ff09f00a590
My question is why are the addresses of objects assigned to array while I get the values while printing the objects?
Can someone suggest a way to get the values returned by class in array in main function?
When you print an object as an individual argument to a print statement in Python 2 or the print() function in Python 3, Python calls str on the object before printing it out.
When you put the object inside a container like a list and print the list, the list gets str called on it, but it in turn calls repr on each of the items it contains, rather than str. To understand why, look at the list [1, '2, 3', 4] and imagine what it would look like if the quotation marks were not included in the output when it was printed. The quotation marks are part of the '2, 3' string's repr.
So to make your class work the way you want, either rename your __str__ method to __repr__ (which will also work for str calls, since the default implementation of __str__ is to call __repr__), or add an additional __repr__ method. Sometimes it's useful to have a __repr__ that returns a less ambiguous string than __str__ does (for instance, it might name the class as well as the arguments). One common convention is to make __repr__ return a string that could be evaled to get an equivalent object again. For your class, that could look like:
def __repr__(self):
return "{}({!r}, {!r})".format(type(self).__name__, self.x, self.y)
I'd also recommend using string formatting like this (or the older %s style if you prefer), rather than concatenating lots of strings together to build your result.
Python containers, e.g. lists use an objects __repr__ method when printing their contents, not their __str__, Define __repr__ instead:
def __repr__(self):
return '('+str(self.x)+','+str(self.y)+')'
If you want a more detailed explanation of __repr__ vs __str__ see here
In searching around the web for usages of custom constructors I see things like this:
def some_constructor(loader, node):
value = loader.construct_mapping(node, deep=True)
return SomeClass(value)
What does the deep=True do? I don't see it in the pyyaml documentation.
It looks like I need it; I have a yaml file generated by a pyyaml representer and it includes node anchors and aliases (like &id003 and *id003); without deep=True I get a shallow map back for those objects containing anchors/aliases.
That you don't see deep=True in the documentation is because you don't normally need to use it as an end-user of the PyYAML package.
If you trace the use of methods in constructor.py that use deep= you come to construct_mapping() and construct_sequence() in class BaseConstructor() and both of these call BaseConstructor.construct_object().
The relevant code in that method to study is:
if tag_suffix is None:
data = constructor(self, node)
else:
data = constructor(self, tag_suffix, node)
if isinstance(data, types.GeneratorType):
generator = data
data = next(generator)
if self.deep_construct:
for dummy in generator:
pass
else:
self.state_generators.append(generator)
and in particular the for loop in there, which only gets executed if deep=True was passed in.
Rougly said if the data comes from a constructor is a generator, then it walks over that data (in the for loop) until the generator is exhausted. With that mechanism, those constructors can contain a yield to create a base object, of which the details can be filled out after the yield. Because of their being only one yield in such constructors, e.g. for mappings (constructed as Python dicts):
def construct_yaml_map(self, node):
data = {}
yield data
value = self.construct_mapping(node)
data.update(value)
I call this a two step process (one step to the yield the next to the end of the method.
In such two-step constructors the data to be yielded is constructed empty, yielded and then filled out. And that has to be so because of what you already noticed: recursion. If there is a self reference to data somewhere underneath, data cannot be constructed after all its children are constructed, because it would have to wait for itself to be constructed.
The deep parameter indirectly controls whether objects that are potentially generators are recursively being built or appended to the list self.state_generators to be resolved later on.
Constructing a YAML document then boils down to constructing the top-level objects and looping over the potentially recursive objects in self.state_generators until no generators are left (a process that might take more than one pass).
The deep argument controls how nested dictionaries are handled during this process.
When deep=True, the construct_mapping method will recursively call itself on any
nested dictionaries it encounters, and merge the resulting dictionaries together.
for example:
a:
b: 1
c: 2
d:
b: 3
When "deep=True"
{'a': {'b': 1, 'c': 2}, 'd': {'b': 3}}
When "deep=False"
{'a': {'c': 2}, 'd': {'b': 3}}
I am trying to use
class reader
def __init__(self, name, booksread)
self.name = name
self.booksread = booksread
while True
option = input("Choose an option: ")
if option = 1:
#What to put here?
I want to create an unlimited number of instances of the reader class, But I could only figure out how to do it a limited number of times by using variables for the class. I also need to call the info later (without losing it). Is it possible to do this with a class? Or would I be better off with a list, or dictionary?
First: if option == 1: is always false in python 3, input only reads strings there.
Second: python lists can be expanded until you run out of RAM.
So the solution would be to create a list in the surrounding code and call append on that every time you have a new item:
mylist = []
while True:
mylist.append(1)
It's perfectly possibly to populate a data structure (such as a list or dict) with instances of a class, given your code example you could put the instances into a list:
class reader
def __init__(self, name, booksread)
self.name = name
self.booksread = booksread
list = []
while True:
option = input("Choose an option: ")
if option == 1:
list.append(reader(name,booksread))
Note: I don't know how you are obtaining the values for 'name' or 'booksread', so their values in the list.append() line are just placeholders
To access the instances in that list, you can then iterate over it, or access elements by their indexes, e.g.
# access each element of the list and print the name
for reader in list:
print(reader.name)
#print the name of the first element of the list
print(list[0].name)
I need to create a structure, in my mind similar to an array of linked lists (where a python list = array and dictionary = linked list). I have a list called blocks, and this is something like what I am looking to make:
blocks[0] = {dictionary},{dictionary},{dictionary},...
blocks[1] = {dictionary},{dictionary},{dictionary},...
etc..
currently I build the blocks as such:
blocks = []
blocks.append[()]
blocks.append[()]
blocks.append[()]
blocks.append[()]
I know that must look ridiculous. I just cannot see in my head what that just made, which is part of my problem. I assign to a block from a different list of dictionary items. Here is a brief overview of how a single block is created...
hold = {}
hold['file']=file
hold['count']=count
hold['mass']=mass_lbs
mg1.append(hold)
##this append can happen several times to mg1
blocks[i].append(mg1[j])
##where i is an index for the block I want to append to, and j is the list index corresponding to whichever dictionary item of mg1 I want to grab.
The reason I want these four main indices in blocks is so that I have shorter code with just the one list instead of block1 block2 block3 block4, which would just make the code way longer than it is now.
Okay, going off of what was discussed in the comments, you're looking for a simple way to create a structure that is a list of four items where each item is a list of dictionaries, and all the dictionaries in one of those lists have the same keys but not necessarily the same values. However, if you know exactly what keys each dictionary will have and that never changes, then it might be worth it to consider making them classes that wrap dictionaries and have each of the four lists be a list of objects. This would be easier to keep in your head, and a bit more Pythonic in my opinion. You also gain the advantage of ensuring that the keys in the dictionary are static, plus you can define helper methods. And by emulating the methods of a container type, you can still use dictionary syntax.
class BlockA:
def __init__(self):
self.dictionary = {'file':None, 'count':None, 'mass':None }
def __len__(self):
return len(self.dictionary)
def __getitem__(self, key):
return self.dictionary[key]
def __setitem__(self, key, value):
if key in self.dictionary:
self.dictionary[key] = value
else:
raise KeyError
def __repr__(self):
return str(self.dictionary)
block1 = BlockA()
block1['file'] = "test"
block2 = BlockA()
block2['file'] = "other test"
Now, you've got a guarantee that all instances of your first block object will have the same keys and no additional keys. You can make similar classes for your other blocks, or some general class, or some mix of the two using inheritance. Now to make your data structure:
blocks = [ [block1, block2], [], [], [] ]
print(blocks) # Or "print blocks" if you're not using Python 3.x
blocks[0][0]['file'] = "some new file"
print(blocks)
It might also be worthwhile to have a class for this blocks container, with specific methods for adding blocks of each type and accessing blocks of each type. That way you wouldn't trip yourself up with accidentally adding the wrong kind of block to one of the four lists or similar issues. But depending on how much you'll be using this structure, that could be overkill.