【问题标题】:List comprehension fails with two set difference objects列表理解因两个集合差异对象而失败
【发布时间】:2019-07-28 21:31:39
【问题描述】:

我有两个集合,想通过列表理解将差异添加到列表中。

使用一组效果很好: diff = [x for x in a.difference(b)]

但是,当我尝试包含第二组 (b) 时,我已经收到来自 PyCharm 的警告,即 语法无效

错误信息:

    diff = [x,y for x in a.difference(b) for y in b.difference(a)]
                  ^
SyntaxError: invalid syntax

下面是一个 Web 示例和我的输入的比较尝试,它在 diff 列表中创建我不想要的列表。

网页示例:my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]

diff = [[x,y] for x in a.difference(b) for y in b.difference(a)]

输出:[[9, 11], [9, 12], [5, 11], [5, 12]]

预期输出:[5,9,11,12]

用两个集合的集合差异创建一个列表的语法是什么?

【问题讨论】:

  • 较短的diff = list(a.difference(b))
  • 你在set.symmetric_difference之后吗?
  • 这对您有帮助吗? stackoverflow.com/questions/3462143/…
  • x,y 之间的逗号导致语法错误 - Python 无法同时添加两个元素以进行列表理解。
  • o 可能是list( a.difference(b) | b.difference(a) ) 或只是list( a ^ b )

标签: python python-3.x list-comprehension


【解决方案1】:

您似乎正在寻找对称差异:

>>> a = set([1,2,3,9,5])
>>> b = set([1,2,3,11,12])
>>> a ^ b
{5, 9, 11, 12}

或者:

>>> a.symmetric_difference(b)
{5, 9, 11, 12}

如果你想用differenceunion 来做:

>>> a.difference(b).union(b.difference(a))
{9, 11, 12, 5}

或者:

>>> (a-b) | (b-a)
{9, 11, 12, 5}

要将set 转换为list

>>> list(a ^ b)
[5, 9, 11, 12]

对于集合理解方法:

>>> set(x for t,u in [(a,b), (b,a)] for x in t if x not in u)
{9, 11, 12, 5}

它获取a 中不在b 中的每个元素,然后是b 中不在a 中的每个元素。

【讨论】:

  • 最后一个似乎不必要地令人费解......但选项列表非常全面!
  • @SillyFreak 最后一个是因为list-comprehension 标签,但你是对的:我永远不会使用它,因为更高级别的功能可用。
【解决方案2】:

您不能在列表理解中执行此操作——它返回的每个元素都是它自己的实体——但你可以使用 itertools 的 chain.from_iterable 来获得你想要的:

list(itertools.chain.from_iterable((x,y) for x in a.difference(b) for y in b.difference(a))

list 调用在那里是因为链函数只返回惰性迭代器。如果你没问题,你可以删除list

【讨论】:

  • 我建议不要使用这个答案。通过展平 OP 得到的对列表来获得差异是倒退的,并且还引入了重复项。 @Alex_P,看看 jferard 的回答,它有很多比这个更清晰、更直接的方法。
【解决方案3】:

让我们分解一下列表理解是非常粗略的语法糖:

diff = []
for x in a.difference(b):
    for y in b.difference(a):
        diff.append([x,y])

两个for是嵌套的!我在x,y 周围添加了方括号,使其成为单个值,以便它可以工作,就像在列表理解中所必需的一样。我希望这能解释你为什么得到[[9, 11], [9, 12], [5, 11], [5, 12]]:一个区别是{9, 5},另一个是{11, 12}。结果是这些集合的笛卡尔积,作为一个列表。

你想要的基本上是一个工会。在“脱糖”列表推导中,这将是一系列 for 循环:

diff = []
for x in a.difference(b):
    diff.append(x)
for y in b.difference(a):
    diff.append(y)

其他答案、cmets 和 this question 已经展示了如何实现您的最终目标,所以我不会重复,但这就是为什么您的代码没有按照您认为的那样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-31
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 2016-07-21
    相关资源
    最近更新 更多