考虑嵌套for循环的C样式,如下所示:
for i = 0; i < n; i++ { for j = i; j < n; j++ { do_something(); } }推荐的python翻译是什么?
遵循Effective Python ,它规定应该避免range(len(something))并且应该尽可能使用enumerate ,我想:
for i, _ in enumerate(some_iter): for j in range(i, len(some_iter)): do_something()但enumerate和range混合似乎不一致。
然而,
for i in range(len(some_iter)): for j in range(i, len(some_iter)): do_something()看起来一致但使用range(len(some_iter)) 。
推荐的Python风格是什么?
Consider a C style nested for loop like so:
for i = 0; i < n; i++ { for j = i; j < n; j++ { do_something(); } }What is the recommended python translation for that?
Following Effective Python, which dictates that range(len(something)) should be avoided and enumerate should be used wherever possible, I'm thinking of:
for i, _ in enumerate(some_iter): for j in range(i, len(some_iter)): do_something()but mix of enumerate and range appears inconsistent.
Whereas,
for i in range(len(some_iter)): for j in range(i, len(some_iter)): do_something()looks consistent but uses range(len(some_iter)).
What is the recommended Python style for this?
最满意答案
如上所述,你实际上并没有使用i或j作为任何东西,所以嵌套循环是无稽之谈; 您可以将计算的次数循环为单个顶级循环。
也就是说,它遵循处理来自给定输入序列的所有唯一配对的常见模式,这是Python中已解决的问题 :
import itertools for x, y in itertools.combinations_with_replacement(some_iter, 2): do_something(x, y)是没有不必要的索引的Pythonic等价物:
for i in range(len(some_iter)): for j in range(i, len(some_iter)): do_something(some_iter[i], some_iter[j])如果您还需要索引,只需将其与enumerate配对:
for (ix, x), (iy, y) in itertools.combinations_with_replacement(enumerate(some_iter), 2): do_something(ix, x, iy, y)使用itertools.combinations_with_replacement (有或没有enumerate )将更有效,更通用:如果您依赖于索引,则将输入限制为序列 ,因此任意迭代( set , dict ,generator表达式等)如果不先将它们转换为序列,它们将无法工作。 使用Pythonic方法意味着您可以接受并使用任何有限迭代,而无需执行手动类型转换和索引。
As written, you're not actually using i or j for anything, so the nested loop is nonsense; you could just loop a calculated number of times as a single top-level loop.
That said, it follows the pattern commonly seen for processing all unique pairings from a given input sequence, and that is a solved problem in Python:
import itertools for x, y in itertools.combinations_with_replacement(some_iter, 2): do_something(x, y)is the Pythonic equivalent, without unnecessary indexing, of:
for i in range(len(some_iter)): for j in range(i, len(some_iter)): do_something(some_iter[i], some_iter[j])If you also needed the index, just pair it with enumerate:
for (ix, x), (iy, y) in itertools.combinations_with_replacement(enumerate(some_iter), 2): do_something(ix, x, iy, y)Using itertools.combinations_with_replacement (with or without enumerate) is going to be more efficient, and more general: If you're relying on indexing, you limit your inputs to sequences, so arbitrary iterables (set, dict, generator expressions, etc.) won't work without converting them to a sequence first. Using the Pythonic approach means you can accept and work with any finite iterable without needing to perform manual type conversions and indexing.
更多推荐
发布评论