Python使用iterable设置更新

时间:2014-12-11 07:39:40

标签: python set iterable

我手边有一个体面大小的文本文件(~23MB)。我正在逐行读取文件,并根据一些外部标准从每行中提取几个单词。为了这个例子,让我们说每行包含至少六个以制表符分隔的值,除了第一个和最后一个之外,我正在拾取所有这些值。

我想输出以这种方式获得的唯一单词集,所以显然我想将提取的单词存储在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的第一种方法有效,而第二种方法使用|=

2 个答案:

答案 0 :(得分:5)

  

从文档中,我了解更新和| =是等效的。此外,因为| =应该接受任何可迭代的......

来自文档:

  

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

文档似乎不符合您的理解。

答案 1 :(得分:4)

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

引用the documentation

  

注意,union()intersection()的非运营商版本,   difference()symmetric_difference()issubset()issuperset()   方法将接受任何iterable作为参数。相比之下,他们的   基于运营商的对应者要求他们的参数是集合。这个   排除了set('abc') & 'cbs'等容易出错的错误结构   更具可读性set('abc').intersection('cbs')