检查 Python 列表中是否有(不)某些东西

新手上路,请多包涵

我有一个 Python 中的元组列表,并且我有一个条件,只有当元组不在列表中时,我才想采用分支(如果它在列表中,那么我不想采用 if 分支)

 if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:

    # Do Something

不过,这对我来说并不适用。我做错了什么?

原文由 Zack 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 644
2 个回答

该错误可能在您的代码中的其他地方,因为它应该可以正常工作:

 >>> 3 not in [2, 3, 4]
False
>>> 3 not in [4, 5, 6]
True

或者使用元组:

 >>> (2, 3) not in [(2, 3), (5, 6), (9, 1)]
False
>>> (2, 3) not in [(2, 7), (7, 3), "hi"]
True

原文由 orlp 发布,翻译遵循 CC BY-SA 3.0 许可协议

如何检查 Python 列表中是否存在(不存在)内容?

最便宜和最易读的解决方案是使用 in 运算符(或者在您的特定情况下, not in )。如文档中所述,

运算符 innot in 测试成员资格。 x in s evaluates to True if x is a member of s , and False otherwise. x not in s 返回 x in s 的否定。

此外,

运算符 not in 被定义为具有 in 的逆真值。

y not in x 在逻辑上与 not y in x 相同。

这里有一些例子:

 'a' in [1, 2, 3]
# False

'c' in ['a', 'b', 'c']
# True

'a' not in [1, 2, 3]
# True

'c' not in ['a', 'b', 'c']
# False

这也适用于元组,因为元组是可散列的(因为它们也是不可变的):

 (1, 2) in [(3, 4), (1, 2)]
#  True

如果 RHS 上的对象定义了一个 __contains__() 方法, in 将在内部调用它,如文档 比较 部分的最后一段所述。

innot in ,由可迭代或实现 __contains__() 方法的类型支持例如,您可以(但不应该)这样做:

 [3, 2, 1].__contains__(1)
# True

in 短路,所以如果你的元素在列表的开头, in 评估更快:

 lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst  # Expected to take longer time.

68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

如果你想做的不仅仅是检查一个项目是否在列表中,有以下选项:

  • list.index 可用于检索项目的索引。如果该元素不存在,则引发 ValueError
  • list.count 如果要计算出现次数,可以使用。

XY 问题:您是否考虑 set s?

问自己这些问题:

  • 您是否需要多次检查某个项目是否在列表中?
  • 此检查是在循环内完成的,还是在重复调用的函数内完成的?
  • 您存储在列表中的项目是否可哈希? IOW,你能给他们打电话 hash 吗?

如果您对这些问题的回答是“是”,则您应该改用 setinlist s 的成员测试是 O(n) 时间复杂度。这意味着 python 必须对列表进行线性扫描,访问每个元素并将其与搜索项进行比较。如果您重复执行此操作,或者列表很大,则此操作会产生开销。

set 对象,另一方面,散列它们的值以进行恒定时间成员检查。还使用 in 完成检查:

 1 in {1, 2, 3}
# True

'a' not in {'a', 'b', 'c'}
# False

(1, 2) in {('a', 'c'), (1, 2)}
# True

如果你很不幸你正在搜索/不搜索的元素在你的列表的末尾,python 将扫描列表直到最后。从下面的时间可以看出这一点:

 l = list(range(100001))
s = set(l)

%timeit 100000 in l
%timeit 100000 in s

2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

提醒一下,只要您存储和查找的元素是可散列的,这是一个合适的选择。 IOW,它们要么必须是不可变类型,要么是实现 __hash__ 的对象。

原文由 cs95 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题