代码之家  ›  专栏  ›  技术社区  ›  Qaswed

将集合转换为列表时会发生什么?

  •  0
  • Qaswed  · 技术社区  · 4 年前

    以下unittest在运行时失败(使用pytest),但在调试时通过:

    def test():
        assert list(set(['B', 'A'])) == ['A', 'B']
    

    我知道 that sets have no order ,但我不知道如何确定 list(s) 如果 s 是一个集合,这在编写单元测试时非常重要。变通办法 mentioned here sorted(s) ,但我想知道 列表 正在运行。

    1 回复  |  直到 4 年前
        1
  •  5
  •   ShadowRanger    4 年前

    list(s) 只是迭代 set 以任何顺序 设置 产生它的输出。问题是 设置 设置 确切地 同样的道理,因为:

    1. 设置
    2. 字符串或类似字节的数据(以及一些像 datetime 对象)使用每个进程种子的哈希加密扰动,因此 不同的 以完全相同的方式构造的条目可能具有完全不同的顺序。

    简而言之,如果你想检查 如果相等,则有三个选项:

    1. 设置 ,例如:

      def test():
          assert set(['B', 'A']) == {'A', 'B'}
      

    2. (CPython/pypypy3.6,任何python3.7+)都使用 dict 模拟 但有保证的插入顺序,例如:

      assert list(dict.fromkeys(['B', 'A'])) == ['B', 'A']  # Passes
      assert list(dict.fromkeys(['B', 'A'])) == ['A', 'B']  # Fails
      

      collections.OrderedDict 可以用来获得保证的顺序,而不是,虽然它的速度较慢,内存更饿。甚至连插入顺序都不一样 口述 , OrderedDict == 是顺序敏感的,所以你可以直接比较 而不是转换回 list

    3. 对于总排序的类型,使用 sorted 如中所述 your linked answer