【问题标题】:Python set update with iterablePython集更新与可迭代
【发布时间】:2015-02-09 15:04:30
【问题描述】:

我手头有一个大小合适的文本文件(~ 23MB)。我正在逐行读取文件,并根据一些外部标准从每一行中提取几个单词。为了这个例子,假设每行至少包含六个制表符分隔的值,除了第一个和最后一个之外,我将选择所有值。

我想输出通过这种方式获得的unique单词集,所以很明显我想将提取的单词存储在set中。此外,由于set.update(other) 比循环遍历other 并使用set.add(elem) 一次添加一个单词要快得多,所以我尝试这样做:

all_words = set()
with open(my_tsv_file) as tsv_file:
    for line in tsv_file:
        wordlist = based_on_some_criteria(line)    # this is a list, not a set
        all_words.update(wordlist)

这很好用。但是当我将all_words.update(wordlist) 替换为all_words |= wordlist 时,出现以下错误:

TypeError: unsupported operand type(s) for |=: 'set' and 'list'

从文档中,我了解到update|= 是等效的。此外,由于|= 应该接受任何可迭代的,我也通过这样做来确认:

import collections
isinstance(wordlist, collections.Iterable)        # returns True

为什么使用set.update 的第一种方法有效,而使用|= 的第二种方法无效?

【问题讨论】:

    标签: python set iterable


    【解决方案1】:

    set 方法如 update 接受任意迭代,而 set 运算符如 ||= 需要集合。

    引用the documentation:

    注意,union()intersection() 的非运营商版本, difference()symmetric_difference()issubset()issuperset() 方法将接受任何可迭代的作为参数。相比之下,他们的 基于运算符的对应项需要设置它们的参数。这 排除像set('abc') & 'cbs'这样容易出错的结构,有利于 更易读的set('abc').intersection('cbs')

    【讨论】:

    • 在文档中进一步说Note, the non-operator versions of the update(), intersection_update(), difference_update(), and symmetric_difference_update() methods will accept any iterable as an argument.
    • @PM2Ring 那是我在答案中引用的段落。 :)
    • 不完全。您引用的段落没有提到update 系列方法;但该段落确实有一些有用的信息,在 Ignacio 和我引用的段落中省略了(这就是我给你投票的原因)。
    • @PM2Ring 确实,你是对的。这些段落是如此相似,以至于我只是偶然地引用了带有附加信息的段落。感谢您的支持。
    【解决方案2】:

    从文档中,我了解到 update 和 |= 是等效的。此外,由于 |= 应该接受任何可迭代的...

    来自文档:

    请注意,update()intersection_update()difference_update()symmetric_difference_update() 方法的非运算符版本将接受任何可迭代作为参数。

    文档似乎与您的理解不一致。

    【讨论】:

    • 啊!完全误解了我第一次阅读的文档。
    猜你喜欢
    • 2022-11-18
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 2015-07-23
    • 1970-01-01
    • 2017-05-30
    • 2018-06-09
    • 1970-01-01
    相关资源
    最近更新 更多