首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >写“`for my_var in my_iterable`”的Pythonic方法

写“`for my_var in my_iterable`”的Pythonic方法
EN

Software Engineering用户
提问于 2019-05-01 00:02:53
回答 1查看 107关注 0票数 -3

python中一个非常常见的模式是:

代码语言:javascript
复制
for something in ['an', 'iterable']:
    func(something)

我几乎总是将可迭代性看作列表(如本例中所示),但它很可能是元组、集合或其他东西。清单是最有表现力和力度的一种方法吗?

同样,我经常看到以下情况:

代码语言:javascript
复制
if something_else in ['another', 'iterable']:
    func(something_else)

在本例中,我们实际上是在搜索something_else (请注意if而不是for),如果可迭代是一个集合,那么它的性能可能会更好。然而,对于非常小的数量来说,这不一定是正确的。一张清单仍然是做这件事的必经之路吗?

EN

回答 1

Software Engineering用户

发布于 2019-05-01 03:40:13

您为第一种情况(迭代)设计的所有选项都是完美的Pythonic。如果您要编写一个for循环并遍历一个可迭代性,那么这个可迭代性实际上并不重要(除非顺序很重要,那么显然要使用tuplelist或一些维护顺序的东西,而不是setdict)。这就是拥有一个可迭代的抽象的全部意义所在!

对于第二种情况(检查包含项的集合),我总是建议使用set**。当然,如果你的list是小的,那也无关紧要。但是随着时间的推移,代码会发生变化,通常这种变化是一种加法,而不是减法。人们通常会扩展集合以包含更多要测试的元素。为成功而设置未来的维护人员(可能包括您自己),而不是性能问题。**此外,set只是工作的正确工具/抽象,因为如果您只想知道某个项是否在集合中,那么复制就无关紧要了。

如果你对表现很好奇,千万别猜!总是测量。即使使用一个小的可迭代性,它也会产生轻微的差异:

代码语言:javascript
复制
In [1]: def test_if_in(x):
   ...:     if x in ['one', 'two', 'three']:
   ...:         return 'Yes'
   ...:     else:
   ...:         return 'No'
   ...:

In [2]: def test_if_in_set(x):
   ...:     if x in {'one', 'two', 'three'}:
   ...:         return 'Yes'
   ...:     else:
   ...:         return 'No'
   ...:

In [3]: %timeit test_if_in('abc')
The slowest run took 10.23 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 167 ns per loop

In [4]: %timeit test_if_in_set('abc')
The slowest run took 11.04 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 116 ns per loop

In [5]: %timeit test_if_in_set('one')
The slowest run took 11.25 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 114 ns per loop

In [6]: %timeit test_if_in('one')
The slowest run took 11.73 times longer than the fastest. This could mean that an intermediate result is being cached.
10000000 loops, best of 3: 109 ns per loop

尽管这两个版本都快得令人目眩,但在元素不是可迭代的情况下,set版本的速度要快1.5倍(这很有意义,因为它必须遍历所有内容,而不是像使用set那样进行O(1)查找)。如果碰巧是可迭代性中的第一项,则情况大致相同。只有当你经常调用这个函数的时候才会有关系。但是,随着可迭代性的增长,情况只会变得更糟。list/tuple/non-hashed-containers很快就开始由set主导。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/391205

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档