[英]python comparing list values to keys in list of dicts
I have a list of dicts a and a list b as shown below. 我有一个字典a列表和一个列表b,如下所示。 len(b) will not always be 4. it may be 2 or 3. I compared values in b to keys in each dict in b.
len(b)并不总是4。它可能是2或3。我将b中的值与b中每个字典的键进行了比较。 I obtained the result shown, which should rightly be of length b but the order is not as desired.
我获得了所示的结果,该结果正确地应为长度b,但顺序不理想。
My 2 problems are: 我的两个问题是:
Here is what I have 这是我所拥有的
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)
My result is 我的结果是
[[0, 1, 7, 0], [0, 0, 12, 0], [5, 0, 8, 0]]
If you notice, for b = 2
ie b[0]
, the result from a[1
] is rightly 7 but it comes after 0 and 1 in my final result even though 2 is the first item in b. 如果您注意到,对于
b = 2
即b[0]
,来自a[1
]的结果恰好是7,但即使2是b中的第一项,它的最终结果还是在0和1之后。
Thank you 谢谢
You can use a list comprehension: 您可以使用列表理解:
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]]
To understand how this works, it sometimes helps to write out the full nested for
loop: 要了解其工作原理,有时有助于写出完整的嵌套
for
循环:
res = []
for d in a:
res_int = []
for i in b:
res_int.append(d[i])
res.append(res_int)
A functional approach is also possible: 功能方法也是可行的:
res = [list(map(d.get, b)) for d in a]
The problem is, you do not iterate with regards to b . 问题是,您没有对b进行迭代。 You iterate with regards to key order in dictionaries inside a .
您可以根据内的字典对键顺序进行迭代。 Thats why output elements are out of order.
这就是为什么输出元素乱序。
For the correct solution, you should iterate with regards to b's items, like this: 为了获得正确的解决方案,您应该对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)
Prints: 印刷品:
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]]
You could also use operator.itemgetter
which provides a neat shorthand to retrieve multiple items in one go: 您还可以使用
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)
Now for example: 现在举个例子:
>>> get_b(a[0])
(7, 0, 1, 0)
The result is a tuple, not a list. 结果是一个元组,而不是列表。 If that's ok you can make a list comprehension or use map:
如果可以,您可以进行列表理解或使用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)]
If it must be lists, it's a bit more cumbersome: 如果必须是列表,那么会比较麻烦:
>>> [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]]
On my system itemgetter
appears to be a bit faster than one-by-one lookup even if we have to convert tuples to lists: 在我的系统上,即使我们必须将元组转换为列表,
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.