我有一个词典a和列表b的列表,如下所示。 len(b)并不总是4.它可能是2或3.我将b中的值与b中每个dict中的键进行比较。我得到了显示的结果,它应该正好是长度为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,但是在我的最终结果中为0和1之后,即使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]
答案 1 :(得分:1)
问题是,您不会针对b 重复。您可以在 a 中的字典中重复关键顺序。这就是输出元素出现故障的原因。
对于正确的解决方案,您应该对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]]
答案 2 :(得分:1)
你也可以使用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)
结果是一个元组,而不是一个列表。如果没关系,你可以制作列表理解或使用地图:
>>> [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