Itertools.chain.from_iterable

2 python python-itertools python-3.x

谁能向我解释一下,这段代码片段到底在做什么?

chained_country_list = set(itertools.chain.from_iterable(country_and_countrycodes)) & set(all_countries)
Run Code Online (Sandbox Code Playgroud)

我知道它运行两个相互对立的列表,最终得到一组唯一值,它存在于它比较的两个列表中。

但是它是如何做到的,以及引擎盖下发生了什么,让我感到困惑。

如果有人可以就这个问题分享一些看法,那将是一个巨大的帮助。

Ash*_*rya 8

让我们分解代码的每个重要元素:

itertools.chain.from_iterable:

基本上,这用于展平嵌套列表,如下所示:

l = [[0], [1, 2], [2], [3, 6], [4], [5, 10]]
list(itertools.chain.from_iterable(l))    
Run Code Online (Sandbox Code Playgroud)

输出:

[0, 1, 2, 2, 3, 6, 4, 5, 10]
Run Code Online (Sandbox Code Playgroud)

& 两个集合之间的运算符:

考虑以下集合 a 和 b 的示例。

a = {1, 2, 3}
b = {2, 3, 4}
a & b
Run Code Online (Sandbox Code Playgroud)

输出:

{2, 3}
Run Code Online (Sandbox Code Playgroud)

所以基本上它获取两个集合之间的公共元素。这里是 2 和 3。

代码整体:

让我们说:

country_and_countrycodes = [('United States', 'US'), ('China', 'CH')]
all_countries = ['United States', 'Mongolia', 'Togo']
Run Code Online (Sandbox Code Playgroud)

现在,第一部分是:

set(itertools.chain.from_iterable(country_and_countrycodes))
Run Code Online (Sandbox Code Playgroud)

这给了我们:

{'CH', 'China', 'US', 'United States'}
Run Code Online (Sandbox Code Playgroud)

所以,它只是从元组中获得了一个平面集。

然后,第二部分是:

set(itertools.chain.from_iterable(country_and_countrycodes)) & set(all_countries)
Run Code Online (Sandbox Code Playgroud)

这给了我们:

{'United States'}
Run Code Online (Sandbox Code Playgroud)

基本上,我们所做的是:

{'CH', 'China', 'US', 'United States'} & {'United States', 'Mongolia', 'Togo'}
Run Code Online (Sandbox Code Playgroud)

由于这里唯一的公共元素是'United States',这就是我们得到的输出。


Kas*_*mvd 5

如果不知道传递给函数的对象的类型和值,就很难判断您的代码做了什么。然而,该函数chain.from_iterable试图创建一个扁平的可迭代对象,country_and_countrycodes它大概应该是一个嵌套的可迭代对象,如嵌套列表。在下一步,该set函数从展平的结果创建一个集合,以便与set(all_countries).

现在作为以下部分的更 Pythonic 替代品:

set(itertools.chain.from_iterable(country_and_countrycodes))
Run Code Online (Sandbox Code Playgroud)

您可以将可迭代对象传递给set().union()函数,以便一次创建一组唯一项的联合集。

例子:

In [2]: set().union(*[[1, 3], [5, 6], [3, 5]])
Out[2]: {1, 3, 5, 6}
Run Code Online (Sandbox Code Playgroud)

因此,您可以将该代码更改为以下内容:

set().union(*country_and_countrycodes) & set(all_countries)
# Or
# set().union(*country_and_countrycodes).intersection(all_countries)
Run Code Online (Sandbox Code Playgroud)