我一直在尝试从python查询中重新格式化一些json数据。我想让我的数据片段成为字典的键。我做了,但我额外带了一张清单和一本字典。我怎样才能去掉它们?我希望有这样的结果:
{
"corps-connecte" :{
"id": 9666888,
"title": "Corps connectu00e9",
"slug": "corps-connecte",
},
"portal-thanos" : {
"id": 9666888,
"title": "Portal thanos",
"slug": "portal-thanos",
},...
}
但实际上我有这个:
[
{
"corps-connecte" :{
"id": 9666888,
"title": "Corps connectu00e9",
"slug": "corps-connecte",
},
},
{
"portal-thanos" : {
"id": 9666888,
"title": "Portal thanos",
"slug": "portal-thanos",
}
}...
]
这是我如何得到上面的数据,也许有一个更简单的方法,我可以正确地重新格式化我的查询?
def artist_artworks(self, artist_id):
artist = self.artist(artist_id)
artworks = []
with ThreadPool(self.threads) as pool:
for artwork in pool.imap(self.artwork, artist["projects"]):
keyList = [artwork["slug"]]
valueList = [artwork]
artworks.append(dict(list(zip(keyList, valueList))))
continue
break
return artworks
def save_artists_json(self, artist):
result = self.save_artist(artist)
json_formatted_str = json.dumps(result)
return json_formatted_str
感谢我认为你的错误是将artworks
作为一个列表并附加到它,而不是将其作为字典并使用新作品更新它:
def artist_artworks(self, artist_id):
artist = self.artist(artist_id)
artworks = {} # <- Initialize as dictionary
with ThreadPool(self.threads) as pool:
for artwork in pool.imap(self.artwork, artist["projects"]):
keyList = [artwork["slug"]]
valueList = [artwork]
artworks.update(dict(list(zip(keyList, valueList)))) # <- update items
continue
break
return artworks
def save_artists_json(self, artist):
result = self.save_artist(artist)
json_formatted_str = json.dumps(result)
return json_formatted_str
你可以这样做:
from pprint import pprint
x = [
{
"corps-connecte" :{
"id": 9666888,
"title": "Corps connectu00e9",
"slug": "corps-connecte",
},
},
{
"portal-thanos" : {
"id": 9666888,
"title": "Portal thanos",
"slug": "portal-thanos",
}
}
]
y = {k: v for d in x for k, v in d.items()}
pprint(y)
{'corps-connecte': {'id': 9666888,
'slug': 'corps-connecte',
'title': 'Corps connecté'},
'portal-thanos': {'id': 9666888,
'slug': 'portal-thanos',
'title': 'Portal thanos'}}
另一个单行解决方案(但可能更低效):
{next(iter(e)): e[next(iter(e))] for e in L}
是Python 3.8中使用walrus:=
操作符的优化版本:
{(k := next(iter(e))): e[k] for e in L}
也可能是更有效的版本:
dict(e.popitem() for e in L)
以上内容的优化版本,如注释所示:
dict(map(dict.popitem, L))
计时不同的选项(运行在Mac OS Big Sur上,即使使用Python 3.9.0)
from pprint import pprint
from timeit import timeit
from copy import deepcopy
x = [
{
"corps-connecte" :{
"id": 9666888,
"title": "Corps connectu00e9",
"slug": "corps-connecte",
},
},
{
"portal-thanos" : {
"id": 9666888,
"title": "Portal thanos",
"slug": "portal-thanos",
}
}
]
# 0.947
print('Items: ',
timeit('L = [z.copy() for z in x]; {k: v for e in L for k, v in e.items()}',
globals=globals()))
# 0.827
print('Next -> Iter: ',
timeit('L = [z.copy() for z in x]; {(k := next(iter(e))): e[k] for e in L}',
globals=globals()))
# 0.912
print('PopItem: ',
timeit('L = [z.copy() for z in x]; dict(e.popitem() for e in L)',
globals=globals()))
# 0.734
print('Map -> PopItem: ',
timeit('L = [z.copy() for z in x]; dict(map(dict.popitem, L))',
globals=globals()))