2012-11-23 77 views
18

我的问题属于字典键。我想为任何单个对象设置一个包含3个键的字典。钥匙必须按顺序排列,并且可以有各种各样的值。例如,Python复杂字典键

dictionary = {(key1,key2,key3) : object} 

KEY1可以是1个到10 KEY2之间的任何值可以是11和20 KEY3之间的任何值可以是任何值21和30

在其中键的顺序之间

放置很重要。

更具体地说,我的钥匙对应的范围X,Y,其中许多对象在左右浮动ž笛卡尔坐标。我希望能够进行排序基于了他们的X,Y的物体的相对位置, z位置。

有没有什么办法可以设置它,还是我需要采取不同的方法? 感谢您的帮助!

+0

应该是可能的,我想。你为什么不尝试? – nhahtdh

+0

看起来你的例子就是你应该尝试的。只要将元组设为键 – jdi

+2

请注意字典实际上是您想要的,因为它意味着没有两个对象可以具有完全相同的xyz位置(因为每个键只保存一个值)。如果你有一个包含x,y和z字段的对象列表,你可以按照'sortedByZ = sorted(objects,key = lambda obj:obj.z)'的方式对它进行排序。 –

回答

11

当然可以,并为此创造一个字符串键 - 只需合并字符串结果你的钥匙像 '' 连接([K1,K2,K3])

Read more about dictionaries.

字典由键索引,可以是任何不可变类型; 字符串和数字始终可以是键。如果 它们只包含字符串,数字或元组,则元组可以用作键;如果元组直接或间接包含任何可变对象,则不能将其用作 键。不能使用列表作为键,因为链表可以使用 索引分配,切片分配,或像append() 和延伸()被修改。

所以你试图使用元组作为一个键,这是行。

请注意,python中的字典没有排序。你可以使用collections.OrderedDict。还要建立正确的排序使用sort/sorted functions与指定的参数键排序你想要的方式。

编辑的样本:

from itertools import product 
myDict = {} 
for x,y,z in product(range(10), range(10,20), range(20,30)): 
    myDict[(x,y,z)] = sum([x,y,z]) 
+0

好的,这是有帮助的。这需要处理订单问题。但我想使用一个对象的x,y,z坐标作为关键字,以获得对存储在我的字典中的另一种不同类型的对象的访问。我不知道如何启用将被接受的每个键的各种值。这有意义吗? – user1846529

+0

@ user1846529你需要为我们提供一个关键输入样例和你需要的东西 - 对我而言,你所说的一切看起来都不错,应该可以工作 –

+0

我的密钥看起来像这样(1.8,12.3,24.9),并且必须有一个将为密钥的每个部分接受的一系列值。所以(1,12,24)也将满足关键标准或(2,13,25)也可以工作... – user1846529

3

希望你会发现这很有用。

>>> from math import sqrt 
>>> def dist(p1, p2): 
...  x1, y1, z1 = p1 
...  x2, y2, z2 = p2 
...  xd = x1 - x2 
...  yd = y1 - y2 
...  zd = z1 - z2 
...  return sqrt((xd ** 2 + yd ** 2 + zd ** 2)) 
>>> myPoint = (0,0,0) 
>>> class MyObject: pass 
>>> myDict = {(1,2,3):MyObject(), (4,5,6):MyObject()} 
>>> sorted([dist(myPoint, point) for point in myDict]) 
10: [3.7416573867739413, 8.774964387392123] 
1

在我看来,你想从键(有序三元组)映射到值(对象)可能无序的集合。如果是这样的话,它很容易使一个复合键出一个有序三元的:

假设obj0是在X,Y,Z坐标(10,20,30)obj1是在X,Y,Z坐标(11,21,31)。然后:

myObjects = {(10,20,30): obj0, 
      (11,21,31): obj1 
      } 

这工作,因为这两个tuple S和int s为不可变的类型

希望帮助

+0

这很接近,但是我希望对象能够为键的每个部分接受各种各样的值。例如,密钥的第一部分可以接受范围从1到100的任何值,第二部分可以接受100到200之间的任何值。我不知道如何做到这一点... – user1846529

+0

您可以轻松地做' (101,208,35):obj1}'。您是否在寻找能够在插入新密钥时检查范围的内容? – inspectorG4dget

+0

当我插入新密钥时,我希望字典知道插入的值在与字典中存储的对象相对应的特定范围内。 – user1846529