Reputation: 181
I have sets of coordinates (in tuples that are the origins) that I am appending into a dictionary, followed by another tuple (the endpoint).
{(0, 0, 0):(10, 10, 10)}
There is a chance that multiple of the same coordinate for the origin will be put into the dict, followed by a different endpoint.
If I try this, they will overwrite, that is why I have tired the method from here where there are mutable objects. The only problem is that if I try and get the x, y and z from it, it turns out the object is not iterable.
Can someone please fix the code from there (will post what I am doing below) or give me a better way to do this? Thanks. (Still new to the mutable objects)
Code:
class coords(object):
def __init__(self,part):
self.part = part
def __str__(self):
return self.part
d = {}
d[coords((0, 10, 0))] = (0 ,0 ,0)
d[coords((0, 10, 0))] = (0 ,1 ,0)
d[coords((0, 10, 0))] = (0 ,2 ,0)
for k in d:
x, y, z = k
print x,y,z
#Here I get the error: "TypeError: 'coords' object is not iterable" at the line "x, y, z = k"
Upvotes: 0
Views: 475
Reputation: 774
I'm a little late to the party, but I think this solution should be on the table. A classic (albeit very basic) way to solve having multiple values at any given key in a hash table is to use a list structure to enumerate all of the values with conflicting keys. Best part of this is that you get to use the defaultdict
type, with no games/tricks.
d = {}
values = [
(coords((0, 10, 0)), (0, 0, 0)),
(coords((0, 10, 0)), (0, 1, 0)),
(coords((0, 10, 0)), (0, 2, 0)),
]
for start, end in values:
if start not in d:
d[start] = []
d[start].append(end)
for start in d:
for end in d[start]:
x, y, z = end
print x,y,z
It's a lot less surprising to me than @Alfe's solution involving having multiple seemingly matching hash keys, and still lets you use the dict as a proper dict. (otherwise, what's the point?)
Also, you don't need to use a list to store your multiple values, I'm just using a list because it's simple/obvious. You can use a set type (for automatic de-duplication), or another dict if you think you can use a secondary hashing algorithm if you are going to have a lot of conflicts, and so on....
Upvotes: 0
Reputation: 35783
The simplest way to get what you need is to use a list of 2-tuples of endpoints:
endpoint_tuples = [((0, 0, 0), (1, 1, 1)), ((2, 3, 4), (5, 6, 7))]
for start_point, end_point in endpoint_tuples:
print start_point
print end_point
If you need to find the endpoint for a certain start point p
:
next(endpoints for endpoints in endpoint_tuples if endpoints[0] == p)
Upvotes: 1
Reputation: 59426
You could use a tuple subclass which has a different behavior concerning equality than the standard tuple.
class htuple(tuple):
def __hash__(self):
return id(self)
def __eq__(self, other):
return self is other
Now you can create htuple
s like this: htuple((1,2,3))
And these htuple
s behave a little like list
s (they are equal only on identity) and a mostly like tuple
s (can be used as dictionary keys, can be iterated, etc.):
{ htuple((1,2,3)): (4,5,6),
htuple((1,2,3)): (7,8,9) }
This is a hack (and I cannot stress this strongly enough). But maybe in your special situation it is a solution you can live with.
Upvotes: 1
Reputation: 1381
You can need to return a string from str not a tuple.Then in the loop just call the dictionary with the key returned from coords str method.
class coords(object):
def __init__(self,part):
self.part = part
def __str__(self):
return str(self.part)
d = {}
d[coords((0, 10, 0))] = (0 ,0 ,0)
d[coords((0, 10, 0))] = (0 ,1 ,0)
d[coords((0, 10, 0))] = (0 ,2 ,0)
for k in d:
x, y, z = d[k]
print x,y,z
Upvotes: 0