[英]Add new key to list of dictionaries with the values from a different dictionaries if matched with value of one key in each dictionary in a list
[英]transpose dictionary (extract all the values for one key from a list of dictionaries)
我有一個這樣的詞典列表:
data = [{'x': 1, 'y': 10},
{'x': 3, 'y': 15},
{'x': 2, 'y': 1},
... ]
我有一個函數(例如matplotlib.axis.plot
),它需要x
和y
值的列表。 所以我必須“轉置”字典“。
第一個問題:你怎么稱呼這個操作? “轉置”正確的術語嗎?
我試過這個,但我正在尋找一種有效的方式(也許有一些特殊的numpy
功能):
x = range(100)
y = reversed(range(100))
d = [dict((('x',xx), ('y', yy))) for (xx, yy) in zip(x,y)]
# d is [{'y': 99, 'x': 0}, {'y': 98, 'x': 1}, ... ]
timeit.Timer("[dd['x'] for dd in d]", "from __main__ import d").timeit()
# 6.803985118865967
from operator import itemgetter
timeit.Timer("map(itemgetter('x'), d)", "from __main__ import d, itemgetter").timeit()
# 7.322326898574829
timeit.Timer("map(f, d)", "from __main__ import d, itemgetter; f=itemgetter('x')").timeit()
# 7.098556041717529
# quite dangerous
timeit.Timer("[dd.values()[1] for dd in d]", "from __main__ import d").timeit()
# 19.358459949493408
有更好的解決方案嗎? 我的疑問是:在這些情況下,每次重新計算字符串'x'
的哈希值?
從這個答案竊取表格
import timeit
from operator import itemgetter
from itertools import imap
x = range(100)
y = reversed(range(100))
d = [dict((('x',xx), ('y', yy))) for (xx, yy) in zip(x,y)]
# d is [{'y': 99, 'x': 0}, {'y': 98, 'x': 1}, ... ]
D={x:y for x,y in zip(range(10),reversed(range(10)))}
def test_list_comp(d):
return [dd['x'] for dd in d]
def test_list_comp_v2(d):
return [(x["x"], x["y"]) for x in d]
def testD_keys_values(d):
return d.keys()
def test_map(d):
return map(itemgetter('x'), d)
def test_positional(d):
return [dd.values()[1] for dd in d]
def test_lambda(d):
return list(imap(lambda x: x['x'], d))
def test_imap_iter(d):
return list(imap(itemgetter('x'), d))
for test in sorted(globals()):
if test.startswith("test_"):
print "%30s : %s" % (test, timeit.Timer("f(d)",
"from __main__ import %s as f, d" % test).timeit())
for test in sorted(globals()):
if test.startswith("testD_"):
print "%30s : %s" % (test, timeit.Timer("f(D)",
"from __main__ import %s as f, D" % test).timeit())
給出以下結果:
test_imap_iter : 8.98246016151
test_lambda : 15.028239837
test_list_comp : 5.53205787458
test_list_comp_v2 : 12.1928668102
test_map : 6.38402269826
test_positional : 20.2046790578
testD_keys_values : 0.305969839705
顯然,最大的勝利是使您的數據格式更接近您已經需要的格式,但您可能無法控制。
就名字而言,我稱之為轉型。
如果您只需要迭代值,可以考慮以下方法:
imap(lambda x: x['x'], d)
為什么不這樣的?
[(x["x"], x["y"]) for x in d]
這將返回包含x和y位置的元組列表。 我不確定它的速度,但它會擺脫lambda開銷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.