关于python:从列表的字典列表理解

List comprehension from dict of lists

我有口述-

1
a = {'b': [1,2,3], 'c':[4,5,6]}

我只想使用列表理解来实现这个输出-

1
[['c', 4], ['c', 5], ['c', 6], ['b', 1], ['b', 2], ['b', 3]]

一个简单的for循环完成了它-

1
2
3
4
x = []
for k, v in a.iteritems():
    for i in v:
        x.append([k, i])

我试着把它转换成清单理解,我做到了-

1
[[k,i] for i in v for k, v in a.items()]

但奇怪的是,我得到了一个输出

1
[['c', 1], ['b', 1], ['c', 2], ['b', 2], ['c', 3], ['b', 3]]

正确的清单理解应该是什么?为什么我的清单理解不起作用?


1
b = [[i, j] for i in a for j in a[i]]

对于列表理解中嵌套的for循环,第一个循环将是您将在第二个循环中使用的变量,例如,在第二个循环中使用i,列表理解中嵌套的for循环很难读取,因此您最好避免使用它。


你就快到了。您面临的主要问题是for循环的顺序。

列表理解中的for循环顺序是基于它们在传统循环方法中出现的顺序。最外层的循环首先出现,然后是内部循环。

1
2
3
4
5
6
7
8
9
10
a = {'b': [1,2,3], 'c':[4,5,6]}
x = []
for k, v in a.items():
    for i in v:
        x.append([k, i])

print(x)

print([[k,i] for i in v for k, v in a.items()])
print([[k,i] for k, v in a.items() for i in v])

产量

1
2
3
[['b', 1], ['b', 2], ['b', 3], ['c', 4], ['c', 5], ['c', 6]]
[['b', 4], ['c', 4], ['b', 5], ['c', 5], ['b', 6], ['c', 6]]
[['b', 1], ['b', 2], ['b', 3], ['c', 4], ['c', 5], ['c', 6]]


你应该先得到k,v,然后迭代v:

1
2
a = {'b': [1,2,3], 'c':[4,5,6]}
print([[k,i] for k, v in a.items() for i in v])

输出:

1
[['c', 4], ['c', 5], ['c', 6], ['b', 1], ['b', 2], ['b', 3]]

注:

[[k,i] for i in v for k, v in a.items()]中,当您试图遍历v时,它没有被定义。

@skam有一个很好的例子:如何解释双循环理解

1
2
3
4
5
6
# Without list comprehension
list_of_words = []
for sentence in text:
    for word in sentence:
       list_of_words.append(word)
return list_of_words

相当于:

1
[word for sentence in text for word in sentence]


您可以尝试使用itertools.product

1
2
3
from itertools import product, chain
a = {'b': [1,2,3], 'c':[4,5,6]}
list(chain(*[product(k, v) for k, v in a.items()]))

结果是

1
[('b', 1), ('b', 2), ('b', 3), ('c', 4), ('c', 5), ('c', 6)]

如果您非常需要列表,可以

1
list(chain(*[[list(item) for item in product(k, v)] for k, v in a.items()]))

输出是:

1
[['b', 1], ['b', 2], ['b', 3], ['c', 4], ['c', 5], ['c', 6]]

以及对表演的一些考验

1
2
3
4
5
6
7
8
In [6]: %timeit [[i, j] for i in a for j in a[i]]
618 ns ± 5.34 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [7]: %timeit list(chain(*[product(k, v) for k, v in a.items()]))
1.26 μs ± 19.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [8]: %timeit list(chain(*[[list(item) for item in product(k, v)] for k, v in a.items()]))
2.61 μs ± 49.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)