【问题标题】:How do I add the contents of an iterable to a set?如何将可迭代的内容添加到集合中?
【发布时间】:2011-05-02 00:26:03
【问题描述】:

将可迭代的所有项添加到现有set"one [...] obvious way" 是什么?

【问题讨论】:

    标签: python set conventions iterable


    【解决方案1】:

    您可以像这样将list 的元素添加到set

    >>> foo = set(range(0, 4))
    >>> foo
    set([0, 1, 2, 3])
    >>> foo.update(range(2, 6))
    >>> foo
    set([0, 1, 2, 3, 4, 5])
    

    【讨论】:

    • 刚刚回顾了我的解释器会话,我实际上尝试了这个,但由于集合表示中的方括号,它认为它已将整个列表添加为集合的元素。我以前从未注意到他们的代表是这样的。
    • 该表示允许您将其直接粘贴回交互式会话中,因为set 构造函数将可迭代对象作为其参数。
    • 请注意,表示只是例如在 Python 3 中为 {1, 2, 3},而在 Python 2 中为 set([1, 2, 3])
    【解决方案2】:

    为了任何可能相信的人的利益,例如在循环中执行aset.add() 的性能与执行aset.update() 相比具有竞争力,下面是一个示例,说明如何在公开之前快速测试您的信念:

    >\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a.update(it)"
    1000 loops, best of 3: 294 usec per loop
    
    >\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "for i in it:a.add(i)"
    1000 loops, best of 3: 950 usec per loop
    
    >\python27\python -mtimeit -s"it=xrange(10000);a=set(xrange(100))" "a |= set(it)"
    1000 loops, best of 3: 458 usec per loop
    
    >\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a.update(it)"
    1000 loops, best of 3: 598 usec per loop
    
    >\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "for i in it:a.add(i)"
    1000 loops, best of 3: 1.89 msec per loop
    
    >\python27\python -mtimeit -s"it=xrange(20000);a=set(xrange(100))" "a |= set(it)"
    1000 loops, best of 3: 891 usec per loop
    

    看起来循环方法的每项成本是update 方法的三倍多。

    使用 |= set() 的成本大约是 update 的 1.5 倍,但只是在循环中添加每个单独项目的成本的一半。

    【讨论】:

      【解决方案3】:

      您可以使用 set() 函数将可迭代对象转换为集合,然后使用标准集合更新运算符 (|=) 将新集合中的唯一值添加到现有集合中。

      >>> a = { 1, 2, 3 }
      >>> b = ( 3, 4, 5 )
      >>> a |= set(b)
      >>> a
      set([1, 2, 3, 4, 5])
      

      【讨论】:

      • 使用 .update 的好处是参数可以是任何可迭代的——不一定是集合——这与您的示例中的 |= 运算符的 RHS 不同。
      • 好点。这只是一个美学选择,因为 set() 可以将一个可迭代对象转换为一个集合,但击键次数是相同的。
      • 这个算子我没见过,以后有它出现我会喜欢用的;谢谢!
      • @eipxen:| 用于联合,& 用于交集,^ 用于获取一个或另一个但不能同时存在的元素。但是在动态类型语言中,有时很难阅读代码并知道飞来飞去的对象的类型,我对使用这些运算符犹豫不决。不认识它们的人(或者甚至没有意识到 Python 允许使用这样的运算符)可能会感到困惑,并认为正在进行一些奇怪的按位或逻辑运算。如果这些运算符也可以处理其他可迭代对象,那就太好了……
      • 对此与.update() 进行了一些时间测试,并在循环中添加单个元素。发现.update() 更快。我将我的结果添加到这个现有的答案中:stackoverflow.com/a/4046249/901641
      【解决方案4】:

      只是一个快速更新,使用 python 3 的计时:

      #!/usr/local/bin python3
      from timeit import Timer
      
      a = set(range(1, 100000))
      b = list(range(50000, 150000))
      
      def one_by_one(s, l):
          for i in l:
              s.add(i)    
      
      def cast_to_list_and_back(s, l):
          s = set(list(s) + l)
      
      def update_set(s,l):
          s.update(l)
      

      结果是:

      one_by_one 10.184448844986036
      cast_to_list_and_back 7.969255169969983
      update_set 2.212590195937082
      

      【讨论】:

        【解决方案5】:

        使用列表理解。

        例如使用列表来缩短可迭代的创建 :)

        >>> x = [1, 2, 3, 4]
        >>> 
        >>> k = x.__iter__()
        >>> k
        <listiterator object at 0x100517490>
        >>> l = [y for y in k]
        >>> l
        [1, 2, 3, 4]
        >>> 
        >>> z = Set([1,2])
        >>> z.update(l)
        >>> z
        set([1, 2, 3, 4])
        >>> 
        

        [编辑:错过了问题的设置部分]

        【讨论】:

        • 我没有看到任何套装?我错过了什么吗?
        【解决方案6】:
        for item in items:
           extant_set.add(item)
        

        为了记录,我认为“应该有一种——最好只有一种——明显的方式来做到这一点”的断言。是假的。它做出了许多具有技术头脑的人所做的假设,每个人的想法都是一样的。对一个人来说显而易见的事情对另一个人来说并不那么明显。

        我认为我提出的解决方案清晰易读,并且可以满足您的要求。我不相信它会影响性能——尽管我承认我可能会遗漏一些东西。但尽管如此,对于其他开发人员来说,它可能并不明显也不可取。

        【讨论】:

        • 啊!像这样在一行上的 for 循环在我的答案中格式化——我永远不会那样做。永远。
        • 你是绝对正确的。我编辑了帖子以修复我的损坏。谢谢:)
        • 您错过了 aset.update(iterable) 以 C 速度循环而 for item in iterable: aset.add(item) 以 Python 速度循环的观点,每个项目都有一个方法查找和一个方法调用 (aarrgghh !!)。
        • 对不起,他在他的问题中没有提到性能,所以我不担心。
        猜你喜欢
        • 2017-08-02
        • 2017-05-11
        • 2012-04-02
        • 2013-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-17
        相关资源
        最近更新 更多