python将列表值与dict列表中的键进行比较
我有一个目录a和目录b的列表,如下所示。len(b)并不总是4。它可能是2或3。我将b中的值与b中每个dict中的键进行了比较。我得到了所示的结果,其长度应为b,但顺序不符合要求 我的两个问题是:python将列表值与dict列表中的键进行比较,python,Python,我有一个目录a和目录b的列表,如下所示。len(b)并不总是4。它可能是2或3。我将b中的值与b中每个dict中的键进行了比较。我得到了所示的结果,其长度应为b,但顺序不符合要求 我的两个问题是: 结果没有按顺序打印。i、 e.不取决于我的列表中哪个值排在第一位 有更好的比较方法吗?(我肯定有)因为len(b)不会总是4岁。它可能更小 这是我的 a = [{0: 0, 1: 1, 2: 7, 3: 0}, {0: 0, 1: 0, 2: 12, 3: 0}, {0: 5, 1: 0, 2: 8,
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中的第一项
谢谢您可以使用列表理解:
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进行迭代。您可以根据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]]
您还可以使用
操作符.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
解决什么问题?这个“结果”的预期含义是什么?不清楚实际的问题是什么。如果你创建一个例子,你会得到更多更好的答案。尤其要确保输入和预期的测试数据是完整的(不是伪数据),并且可以轻松地剪切和粘贴到编辑器中,以允许测试建议的解决方案。如果您照样复制我的代码,它就会工作。我的问题是顺序和我进行比较的方式。请帮助我了解否决票,以便我能够改进。我在实践中学习,你们一直在帮助我是的,我同意。我一直在练习。我的大多数实践都附带了很多for循环和if语句。这就是为什么我试图理解更短的方法。谢谢你的回答。你最后的回答非常简短。但愿我能用那种方式写我所有的代码。开始理解它。非常好的解决方案!哦,好的。那么您对包含所需输出的变量进行迭代了吗?是的。从您的帖子中,我了解到您想要订购的是
b
。所以我试着用这种方式更正你的代码。