2

我有一个看起来像这样的字典

db = {
'ObjectID': ['-1', '6', '10', '13', '13', '13', '-1', '-1', '-1', '-1', '-1', '-1'], 
'Test_value': ['25', '0,28999999', '100,00000000', 'Geometry', '126641,847400000000', '473106,185600000030', ' ', ' ', ' ', ' ', ' ', ' '], 
'Has_error': ['true', 'true', 'true', 'true', 'true', 'true', 'false', 'false', 'false', 'false', 'false', 'false'], 
'Message': ['Table row counts are different', 'ObjectID 6 is different for Field DIKTE_BRUGDEK', 'ObjectID 10 is different for Field RICHTING_1',                'ObjectID 13 is different for Field GEOMETRIE', 'ObjectID 13 is different for Field X', 'ObjectID 13 is different for Field Y', 'Shape types are the          same', 'Feature types are the same', 'Feature class extents are the same', 'GeometryDefs are the same', 'Field properties are the same', 'Spatial             references are the same'], 'Identifier': ['Table', 'FeatureClass', 'FeatureClass', 'FeatureClass', 'FeatureClass', 'FeatureClass', 'FeatureClass',            'FeatureClass', 'FeatureClass', 'GeometryDef', 'Field', 'SpatialReference'], 
'Base_value': ['23', '0,19000000', '394,00000000', 'Geometry', '126530,700000000000', '473095,700000000010', ' ', ' ', ' ', ' ', ' ', ' ']}

我想根据“ObjectID”列表中的条目将其分解为一个较小的子集,即-1。我的第一次尝试是建立值的索引,例如:

filter_ind = []
for k,v in db.iteritems():
    for i in xrange(len(v)):
            if (k == 'ObjectID') and (int(v[i]) != -1):
                filter_ind.append(i) 

然后我尝试构建一个新的字典,使用 filter_ind 作为排序过滤器: dict((k,v[i]) for i in filter_ind for k, v in db.iteritems())

我得到的只是最后一场比赛,因为v不再是列表: {'ObjectID':'13','Test_value':'473106,185600000030','Has_error':'true', 'Message':'ObjectID 13 is different for Field Y', 'Identifier':'FeatureClass','Base_value': '473095,700000000010'}

问题:是否有另一种方法可以根据自身内部的特定值过滤 dict?如果这被认为是一种相对直接的方法,那么使用索引作为过滤器来创建新字典的聪明方法是什么?已经谢谢了。

4

6 回答 6

4

我认为你有点过于复杂了。首先,不需要嵌套循环。您可以通过以下方式获得所需的索引:

oids = db['ObjectID']
for i, id in enumerate(oids):
    if id != -1
        filter_ind.append(i) 

或者更简洁地说,

filter_ind = [i for i, id in enumerate(oids) if id != '-1']

然后,您可以使用 id 过滤各个列表:

dict((key, [val[i] for i in filter_ind]) for key, val in db.iteritems())
于 2012-07-11T16:26:44.617 回答
2

这是另一种选择:

from operator import itemgetter

iget = itemgetter(*(i for i, id in enumerate(db['ObjectID']) if int(id) != -1))
result = dict((k, list(iget(v))) for k, v in db.items())
于 2012-07-11T16:34:18.590 回答
2

这是我做的:

new_db=db.copy()
fltr=[x=='-1' for x in new_db['ObjectID']] #Not actually necessary, but makes the code a little more readable

for k,v in new_db.items():
    new_db[k]=[x for i,x in enumerate(new_db[k]) if fltr[i]]  #replace old lists with new filtered ones.

这与 senderle 发布的答案非常相似(我认为)。我使用布尔列表,而另一个答案使用索引。我的可能效率不高,但我更容易阅读/理解。

于 2012-07-11T16:29:44.630 回答
1

这实际上是您可以使用的罕见场合itertools.compress

from itertools import compress

sels = [x != '-1' for x in db['ObjectID']]
comp = {key: list(compress(vals, sels)) for key, vals in db.items()}
于 2014-06-04T21:41:09.760 回答
1

如果您使用的是 2.7:

from itertools import compress
indexes = [(x != -1) for x in db['ObjectID']]
result = dict((k, compress(v, indexes)) for k, v in db.iteritems())
于 2012-07-11T16:39:02.233 回答
0

我喜欢这个:

[dict(zip(db.keys(),e)) for e in zip(*db.values()) if e[0]!='-1']

它返回一个字典列表,不包括带有 -1 的字典。

于 2012-07-11T17:10:37.740 回答