理解Python';s itertools.chain和next

理解Python';s itertools.chain和next,python,for-loop,itertools,next,code-translation,Python,For Loop,Itertools,Next,Code Translation,我试图将一行Python代码转换为JavaScript,但我对Python的知识有限,很难理解它 有人能解释一下下面的代码吗?point\u orientation函数并不重要,它只返回True/False i_extend=next((i为i在itertools.chain(范围(i_start+1,len(p)),范围(0,i_start+1))如果不是点方向(p[i-1],p[i],p[(i+1)%len(p)]) 这里的itertools.chain只是从这两个范围中列出一个列表,在本文

我试图将一行Python代码转换为JavaScript,但我对Python的知识有限,很难理解它

有人能解释一下下面的代码吗?
point\u orientation
函数并不重要,它只返回True/False

i_extend=next((i为i在itertools.chain(范围(i_start+1,len(p)),范围(0,i_start+1))如果不是点方向(p[i-1],p[i],p[(i+1)%len(p)])

这里的itertools.chain只是从这两个范围中列出一个列表,在本文中可以更好地表示为
(*range(i_start+1,len(p)),*range(i_start+1))
。(拆包:)

next()
只获取iterable的“next”项,这里因为它直接在生成器表达式上操作,所以它用于获取第一项
next(iter([1,2,3])
,类似地,将返回
1

如果有帮助的话,可以用这种方式写得更地道一点--

--或者,如果
next()
仍然给您带来麻烦,您可以这样查看(请注意末尾的
[0]
):

它的意思是“在
范围(i_开始+1,len(p))
范围(0,i_开始+1)
(如果第一个范围没有)中查找第一个元素
i
,使得
点方向(p[i-1],p[i],p[(i+1)%len(p)]
为假”。如果没有这样的
i
,它将引发异常

这里是更详细的Python:

def check(i):
    return point_orientation(p[i - 1],
                             p[i],
                             p[(i + 1) % len(p)])


def find_i_extend():
    for i in range(i_start + 1, len(p)):
        if not check(i):
            return i

    for i in range(0, i_start + 1):
        if not check(i):
            return i


i_extend = find_i_extend()

chain
将两个迭代器缝合成一个迭代器。在这里,它被用来帮助模拟一个从特定点开始的闭合循环。注意

range(0, len(p)) == chain(range(0, i_start+1), range(i_start+1, len(p))
给定的代码将参数交换到
,以便将类似
[0,1,2,…,10]
的序列转换为类似
[5,6,…,10,0,1,…,4]
的序列。谓词的三个参数只是循环中的相邻项,
(i+1)%len(p)
在序列末尾进行换行
next
仅用于获取结果序列的第一个元素

如果您放弃用一行代码来表达这一点,您可能会编写以下更易于理解的代码:

n = len(p)
for i in range(i_start + 1, i_start + 1 + n):
    index_before = (i - 1) % n
    index_at = i % n
    index_after = (i+1) % n
    if not point_orientation(p[index_before], p[index_at], p[index_after])
        i_extend = y
        break

我们在一个范围内迭代,并对循环中的每个索引进行模运算。如果谓词通过,我们将
i_extend
设置为当前点并中断。否则,我们继续迭代,假设其中一个点最终会成功。

链基本上是广义到任意迭代器的列表串联<代码>列表(chain(list1,list2))==list1+list2
。我不知道为什么这会被否决。这段代码需要python知识才能破译。它查看两个整数范围,并返回第一个满足
如果不满足点方向要求的整数。它通过
next
完成,以便在第一次匹配时停止操作。这可以在javascript中使用两个
for
循环来获得不同的范围,并在每个循环中复制测试。代码是合理的-使用
next
chain
意味着不必在内存中保存数据结构<代码>(*range(i_start+1,len(p)),*range(i_start+1))
创建一个元组。这段代码的目的是根据一个条件测试多个范围,找到第一个匹配项,并停止任何其他计算。@AlexHall这是公平的,我完全忘记了
chain()
返回的是迭代器而不是列表。(还抱怨围绕函数调用参数的空格)——请注意,我不建议使用listcomp而不是
next()
,因为最后一个示例只是将
next()
引入到OP的透视图中。只要我们谈论的是python 3.x,
chain
range
都是迭代器。它们不应该扩展为元组,因为关键是在第一次匹配时停止迭代,而不是扩展所有内容。这确实是关键所在。再次重申:我的最后一个例子并不是建议OP用列表替换他们的下一个(gencomp)。这是next()的一个例子,它的意思是让他们了解next()的作用。
range(0, len(p)) == chain(range(0, i_start+1), range(i_start+1, len(p))
n = len(p)
for i in range(i_start + 1, i_start + 1 + n):
    index_before = (i - 1) % n
    index_at = i % n
    index_after = (i+1) % n
    if not point_orientation(p[index_before], p[index_at], p[index_after])
        i_extend = y
        break