1

我不确定我是否使用了正确的术语——我可能称之为合并操作?简单搭配?

我有两本词典。其中之一包含标签 ID 列表。另一种是标签 ID 和标签 ID 名称之间的对应关系。我想匹配 ID 并在第一个字典中包含标签名称。

所以,第一个字典看起来像这样:

>>> myjson
[
{"tags" : ["1","3"],"otherdata" : "blah"},
{"tags" : ["2","4"],"otherdata" : "blah blah"}
]

第二个字典如下所示:

>>> tagnames
[
{"id": "1", "name":"bassoon"},
{"id": "2", "name":"banjo"},
{"id": "3", "name":"paw paw"},
{"id": "4", "name":"foxes"}
]

要将 myjson 中的标签 ID 替换为标签 ID 名称,我目前正在这样做:

data = []
for j in myjson:
    d = j
    d['tagnames'] = [i['name'] for i in tagnames for y in d['tags'] if y==i['id']]
    data.append(d)

我想要的输出是这样的:

>>> data
[
{"tags" : ["1","3"],"otherdata" : "blah", "tagname" : ["bassoon","paw paw"]},
{"tags" : ["2","4"],"otherdata" : "blah blah", "tagname": ["banjo","foxes"]}
]

我得到了正确的输出,但它似乎真的很慢。我知道它每次都在对 myjson 中的每个元素进行完整迭代 x 对标记名中的每个元素进行完整迭代(那是 mxn 吗?nxn?),这会很慢,但也许有更智能的语法或技巧来加速它? 只遍历数组一次而不是 n 次?

哦,如果有人可以建议一种使用光滑映射或功能方法而不是外部 forloop 来完成此任务的方法,那将是很酷的。

4

1 回答 1

2

您想将您的标记名列表转换为字典:

tagnames_map = {t['id']: t['name'] for t in tagnames}

现在您可以更快地找到匹配的标记名;您的代码已经进行了就地更改,因此我将其简化为:

for d in myjson:
    d['tagnames'] = [tagnames_map[t] for t in tagnames_map.viewkeys() & d['tags']]

dict.viewkeys()方法返回一个字典视图对象,其作用类似于一个集合。我们将该集合与您的标签列表相交,从而产生一系列标签,这些标签都列在tagnames_map. 通过这样做,我们不必担心地图中缺少任何标签。

如果您使用的是 Python 3,那么您只需tagnames_map.keys()直接使用;在 Python 3 中.keys().values()items()方法已更改为始终返回字典视图对象。

如果您想制作副本,请使用d.copy()

data = []
for d in myjson:
    d = d.copy()
    d['tagnames'] = [tagnames_map[t] for t in tagnames_map.viewkeys() & d['tags']]
    data.append(d)

dict.copy()创建一个浅拷贝;不复制可变值,新的字典只会引用相同的值。因为您没有在这里更改值,所以很好。

针对您的示例输入运行此命令会给出:

>>> pprint(data)
[{'otherdata': 'blah', 'tagnames': ['bassoon', 'paw paw'], 'tags': ['1', '3']},
 {'otherdata': 'blah blah',
  'tagnames': ['banjo', 'foxes'],
  'tags': ['2', '4']}]
于 2013-05-10T14:19:14.220 回答