代码之家  ›  专栏  ›  技术社区  ›  Adam Matan

python:添加要设置的列表?

  •  174
  • Adam Matan  · 技术社区  · 16 年前

    在python 2.6解释器上测试:

    >>> a=set('abcde')
    >>> a
    set(['a', 'c', 'b', 'e', 'd'])
    >>> l=['f','g']
    >>> l
    ['f', 'g']
    >>> a.add(l)
    Traceback (most recent call last):
      File "<pyshell#35>", line 1, in <module>
        a.add(l)
    TypeError: list objects are unhashable
    

    我认为我不能将列表添加到集合中,因为Python无法判断我是否已经添加了同一个列表两次。有解决办法吗?

    编辑:我想添加列表本身,而不是它的元素。

    12 回复  |  直到 6 年前
        1
  •  150
  •   Community Mohan Dere    8 年前

    不能向集合中添加列表,因为列表是可变的,这意味着您可以在将列表添加到集合后更改列表的内容。

    但是,可以向集合中添加元组,因为不能更改元组的内容:

    >>> a.add(('f', 'g'))
    >>> print a
    set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])
    

    编辑 :一些解释:文档定义了 set 作为 不同哈希对象的无序集合。 对象必须是可散列的,这样查找、添加和删除元素的速度就可以比每次执行这些操作时查看每个单独的元素的速度更快。使用的具体算法在 Wikipedia article . pythons散列算法解释如下 effbot.org 蟒蛇 __hash__ 中的函数 python reference .

    一些事实:

    • 集合元素 以及 字典键 必须是可哈希的
    • 某些不可显示的数据类型:
      • list 使用 tuple 相反
      • 设置 使用 frozenset 相反
      • dict :没有官方对应,但有一些 recipes
    • 对象实例在默认情况下是可以散列的,每个实例都有一个唯一的散列。您可以按照python引用中的说明重写此行为。
        2
  •  392
  •   Boris Verkhovskiy Brian Clapper    6 年前

    使用 set.update() |=

    >>> a = set('abc')
    >>> l = ['d', 'e']
    >>> a.update(l)
    >>> a
    {'e', 'b', 'c', 'd', 'a'}
    
    >>> l = ['f', 'g']
    >>> a |= set(l)
    >>> a
    {'e', 'b', 'f', 'c', 'd', 'g', 'a'}
    

    编辑:如果您想添加列表本身而不是它的成员,那么您必须使用元组,很遗憾。集合成员必须是 hashable .

        3
  •  63
  •   Community Mohan Dere    8 年前

    将列表元素添加到集合中 使用 update

    https://docs.python.org/2/library/sets.html

    s.update(t):返回集合s,从t添加元素

    例如。

    >>> s = set([1, 2])
    >>> l = [3, 4]
    >>> s.update(l)
    >>> s
    {1, 2, 3, 4}
    

    如果你愿意的话 将整个列表作为单个元素添加 对于集合,不能这样做,因为列表不可哈希。您可以添加一个元组,例如 s.add(tuple(l)) . 也见 TypeError: unhashable type: 'list' when using built-in set function 更多信息。

        4
  •  38
  •   alvas    12 年前

    希望这有助于:

    >>> seta = set('1234')
    >>> listb = ['a','b','c']
    >>> seta.union(listb)
    set(['a', 'c', 'b', '1', '3', '2', '4'])
    >>> seta
    set(['1', '3', '2', '4'])
    >>> seta = seta.union(listb)
    >>> seta
    set(['a', 'c', 'b', '1', '3', '2', '4'])
    
        5
  •  14
  •   the Tin Man    13 年前

    请注意功能 set.update() . 文件上说:

    使用自身和其他集合更新集合。

        6
  •  8
  •   SilentGhost    16 年前

    列表对象不可显示 . 不过,您可能想将它们转换成元组。

        7
  •  5
  •   user135331    16 年前

    集合不能具有可变(可更改)元素/成员。列表是可变的,不能是集合的成员。

    因为集合是可变的,所以不能有集合! 不过,你可以有一套冰冻的。

    (同样的“可变性要求”也适用于口述的按键。)

    其他答案已经给了你代码,我希望这能给你一点启发。 我希望亚历克斯·马泰利能更详细地回答。

        8
  •  4
  •   hughdbrown    16 年前

    要添加元组,而不是列表:

    >>> a=set('abcde')
    >>> a
    set(['a', 'c', 'b', 'e', 'd'])
    >>> l=['f','g']
    >>> l
    ['f', 'g']
    >>> t = tuple(l)
    >>> t
    ('f', 'g')
    >>> a.add(t)
    >>> a
    set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])
    

    如果您有一个列表,可以转换为元组,如上图所示。元组是不可变的,因此可以将其添加到集合中。

        9
  •  3
  •   Noah    16 年前

    您将要使用可散列的元组(不能散列列表之类的可变对象)。

    >>> a = set("abcde")
    >>> a
    set(['a', 'c', 'b', 'e', 'd'])
    >>> t = ('f', 'g')
    >>> a.add(t)
    >>> a
    set(['a', 'c', 'b', 'e', 'd', ('f', 'g')])
    
        10
  •  3
  •   Dunes    14 年前

    我发现我今天也需要做类似的事情。该算法知道何时创建了一个需要添加到集合中的新列表,但不知道何时才能完成对列表的操作。

    不管怎样,我想要的行为是使用 id 而不是 hash .所以我发现 mydict[id(mylist)] = mylist 而不是 myset.add(mylist) 提供我想要的行为。

        11
  •  2
  •   keios    11 年前

    我通常是这样做的:

    def add_list_to_set(my_list, my_set):
        [my_set.add(each) for each in my_list]
    return my_set
    
        12
  •  -3
  •   Ivan Jeffrey Zhao    8 年前

    应该这样做:

    set(tuple(i) for i in L)