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循环的顺序。
列表理解中的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]] |
你应该先得到
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]] |
注:
在
@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) |