[英]python comparing list values to keys in list of dicts
我有一個字典a列表和一個列表b,如下所示。 len(b)並不總是4。它可能是2或3。我將b中的值與b中每個字典的鍵進行了比較。 我獲得了所示的結果,該結果正確地應為長度b,但順序不理想。
我的兩個問題是:
這是我所擁有的
a = [{0: 0, 1: 1, 2: 7, 3: 0}, {0: 0, 1: 0, 2: 12, 3: 0}, {0: 5, 1: 0, 2: 8, 3: 0}]
b = [2, 0, 1, 3]
c = []
for i in a:
x = []
for k, v in i.items():
if k == b[0]:
x.append(v)
if k == b[1]:
x.append(v)
if k == b[2]:
x.append(v)
if k == b[3]:
x.append(v)
c.append(x)
print(c)
我的結果是
[[0, 1, 7, 0], [0, 0, 12, 0], [5, 0, 8, 0]]
如果您注意到,對於b = 2
即b[0]
,來自a[1
]的結果恰好是7,但即使2是b中的第一項,它的最終結果還是在0和1之后。
謝謝
您可以使用列表理解:
res = [[d[i] for i in b] for d in a]
print(res)
[[7, 0, 1, 0], [12, 0, 0, 0], [8, 5, 0, 0]]
要了解其工作原理,有時有助於寫出完整的嵌套for
循環:
res = []
for d in a:
res_int = []
for i in b:
res_int.append(d[i])
res.append(res_int)
功能方法也是可行的:
res = [list(map(d.get, b)) for d in a]
問題是,您沒有對b進行迭代。 您可以根據內的字典對鍵順序進行迭代。 這就是為什么輸出元素亂序。
為了獲得正確的解決方案,您應該對b的項進行迭代,如下所示:
a = [{0: 0, 1: 1, 2: 7, 3: 0}, {0: 0, 1: 0, 2: 12, 3: 0}, {0: 5, 1: 0, 2: 8, 3: 0}]
b = [2, 0, 1, 3]
c = []
for a_dict in a:
x = []
for b_element in b:
if b_element in a_dict:
x.append(a_dict[b_element])
print("Appending %ss value %s to X! new X: %s" % (b_element, a_dict[b_element], str(x)))
c.append(x)
print(c)
印刷品:
Appending Key:2s Value:7 to X! new X: [7]
Appending Key:0s Value:0 to X! new X: [7, 0]
Appending Key:1s Value:1 to X! new X: [7, 0, 1]
Appending Key:3s Value:0 to X! new X: [7, 0, 1, 0]
Appending Key:2s Value:12 to X! new X: [12]
Appending Key:0s Value:0 to X! new X: [12, 0]
Appending Key:1s Value:0 to X! new X: [12, 0, 0]
Appending Key:3s Value:0 to X! new X: [12, 0, 0, 0]
Appending Key:2s Value:8 to X! new X: [8]
Appending Key:0s Value:5 to X! new X: [8, 5]
Appending Key:1s Value:0 to X! new X: [8, 5, 0]
Appending Key:3s Value:0 to X! new X: [8, 5, 0, 0]
[[7, 0, 1, 0], [12, 0, 0, 0], [8, 5, 0, 0]]
您還可以使用operator.itemgetter
,它提供了一種簡潔的速記形式,可以一次性檢索多個項目:
>>> a = [{0: 0, 1: 1, 2: 7, 3: 0}, {0: 0, 1: 0, 2: 12, 3: 0}, {0: 5, 1: 0, 2: 8, 3: 0}]
>>> b = [2, 0, 1, 3]
>>>
>>> from operator import itemgetter
>>> get_b = itemgetter(*b)
現在舉個例子:
>>> get_b(a[0])
(7, 0, 1, 0)
結果是一個元組,而不是列表。 如果可以,您可以進行列表理解或使用map:
>>> [get_b(d) for d in a]
[(7, 0, 1, 0), (12, 0, 0, 0), (8, 5, 0, 0)]
>>> list(map(get_b, a))
[(7, 0, 1, 0), (12, 0, 0, 0), (8, 5, 0, 0)]
如果必須是列表,那么會比較麻煩:
>>> [list(get_b(d)) for d in a]
[[7, 0, 1, 0], [12, 0, 0, 0], [8, 5, 0, 0]]
>>> list(map(list, map(get_b, a)))
[[7, 0, 1, 0], [12, 0, 0, 0], [8, 5, 0, 0]]
在我的系統上,即使我們必須將元組轉換為列表, itemgetter
看起來也比一對一查找要快一些:
>>> from timeit import timeit
>>>
>>> def multi_get(a, b):
... get_b = itemgetter(*b)
... return [[*get_b(d),] for d in a]
...
>>> def multi_get_tuple(a, b):
... get_b = itemgetter(*b)
... return [get_b(d) for d in a]
...
>>> timeit("multi_get_tuple(a, b)", globals=globals(), number=1000000)
0.9130640690000291
>>> timeit("multi_get(a, b)", globals=globals(), number=1000000)
1.0864301430010528
>>> timeit("[[d[i] for i in b] for d in a]", globals=globals(), number=1000000)
1.40757593699891
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.