从列表字典生成列表推导式

4

我有一个字典-

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

我想只使用列表推导式来实现以下输出-
[['c', 4], ['c', 5], ['c', 6], ['b', 1], ['b', 2], ['b', 3]]

使用简单的for循环即可完成 -

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

尝试将其转换为列表推导式,我做了这个 -
[[k,i] for i in v for k, v in a.items()]

但是对我来说很奇怪,我得到了一个输出。
[['c', 1], ['b', 1], ['c', 2], ['b', 2], ['c', 3], ['b', 3]]

什么是正确的列表推导式,为什么我的列表推导式不起作用?
4个回答

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

对于列表推导式中的嵌套for循环,第一个循环的变量将在第二个循环中使用,例如在这里,i在第二个循环中被使用。由于列表推导式中的嵌套循环难以阅读,因此最好避免使用。


为什么在列表推导式中,a.items() 的右侧而不是左侧? - Sushant
抱歉,我没有理解你的问题? - Mohit Solanki
1
我们如何决定列表推导中for循环的顺序? - Sushant
嵌套的列表推导式中,第一个循环是你将在第二个循环中使用的变量,比如这里的例子中i在第二个循环中被使用。嵌套的列表推导式很难阅读,因此最好避免使用。 - Mohit Solanki
谢谢,我已经点赞了你的回答。一个完整的答案应该包含这个解释。 - Sushant

4
你应该先得到 k,v,然后遍历 v:
a = {'b': [1,2,3], 'c':[4,5,6]}
print([[k,i] for k, v in a.items() for i in v])

输出:

[['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时,v未定义。

@Skam提供了一个很好的例子:如何解释双重循环推导式

# Without list comprehension
list_of_words = []
for sentence in text:
    for word in sentence:
       list_of_words.append(word)
return list_of_words

等价于:

[word for sentence in text for word in sentence]

为什么在列表推导式中a.items()的右侧而不是左侧? - Sushant
这与如何解释双重循环理解有关。在您的实现中,当您尝试迭代它时,v尚未定义。 - madjaoue
如果您在答案中添加这个,那将完全回答我的问题,这会很有帮助。 - Sushant
1
谢谢,我已经点赞了你的回答。Argo在你之前提供了完整的答案,所以我接受了他的回答。 - Sushant

4

你已经接近成功了。你遇到的主要问题是由于for循环的顺序引起的。

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

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])

输出

[['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
你可以尝试使用 itertools.product
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()]))

结果是。
[('b', 1), ('b', 2), ('b', 3), ('c', 4), ('c', 5), ('c', 6)]

如果你非常需要列表的列表,可以这样做:

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

输出为:
[['b', 1], ['b', 2], ['b', 3], ['c', 4], ['c', 5], ['c', 6]]

并且进行了一些性能测试

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接