Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python itertools和跨步列表分配_Python_Slice_Itertools - Fatal编程技术网

Python itertools和跨步列表分配

Python itertools和跨步列表分配,python,slice,itertools,Python,Slice,Itertools,给定一个列表,例如x=[True]*20,我想将False分配给其他每个元素 x[::2] = False 引发TypeError:必须将iterable分配给扩展切片 所以我天真地认为你可以这样做: x[::2] = itertools.repeat(False) 或 然而,据我所知,这导致了一个无限循环。为什么会有一个无限循环?是否有一种替代方法不涉及在赋值之前知道切片中元素的数量 编辑:我知道x[::2]=[False]*len(x)/2在这种情况下起作用,或者在更一般的情况下,您可以

给定一个列表,例如
x=[True]*20
,我想将
False
分配给其他每个元素

x[::2] = False
引发
TypeError:必须将iterable分配给扩展切片

所以我天真地认为你可以这样做:

x[::2] = itertools.repeat(False)

然而,据我所知,这导致了一个无限循环。为什么会有一个无限循环?是否有一种替代方法不涉及在赋值之前知道切片中元素的数量


编辑:我知道
x[::2]=[False]*len(x)/2
在这种情况下起作用,或者在更一般的情况下,您可以在右侧找到一个乘法器表达式。我试图理解是什么导致itertools无限循环,以及为什么列表分配的行为不同于numpy数组分配。我认为python一定有一些基本的东西,我对此有所误解。我最初还认为,可能是出于性能原因,您更喜欢itertools而不是列表理解或创建另一个n元素列表。

您在这段代码中试图做的事情与您的想法不同(我怀疑) 例如:
x[::2]
将返回一个包含x的每个
奇数
元素的切片,因为x的大小为20,
切片的大小为10,但您正在尝试为其指定大小为1的不可替代项

要成功使用您拥有的代码,您需要执行以下操作:

x = [True]*20
x[::2] = [False]*10
wich会将大小为10的iterable分配给大小为10的切片

为什么要在黑暗中工作?使用

len(x[::2])  
等于10,然后使用

x[::2] = [False]*len(x[::2])
您还可以执行以下操作:

x = [True if (index & 0x1 == 0) else False for index, element in enumerate(x)]

编辑:由于操作编辑

on循环表示它
无限重复。
这意味着它将通过给定的迭代器持续“循环”

Repeat有一个类似的实现,但是声明它
无限期运行,除非指定了times参数。

问题代码中没有这样做。因此,两者都将导致无限循环

关于
itertools
更快的评论。是的,itertools通常比其他实现更快,因为它们经过优化,能够以创建者所能达到的速度运行

但是,如果不想重新创建列表,可以使用
生成器表达式
,例如:

x = (True if (index & 0x1 == 0) else False for index, element in enumerate(x))
它们不会将所有元素都存储在内存中,而是在需要时生成它们,但是,生成器功能可能会耗尽

例如:

x = [True]*20
print(x)
y = (True if (index & 0x1 == 0) else False for index, element in enumerate(x))
print ([a for a in y])
print ([a for a in y])
将打印
x
,然后是生成器中的元素
y
,然后是空列表,因为生成器已用完。

请尝试以下操作:

l = len(x)
x[::2] = itertools.repeat(False, l/2 if l % 2 == 0 else (l/2)+1)
您的原始解决方案以无限循环结束,因为这是
repeat
应该做的,从以下方面:

制作一个迭代器,反复返回对象。除非指定了times参数,否则将无限期运行


切片
x[::2]
的长度正好是
len(x)/2
元素,因此您可以通过以下方式实现所需:

x[::2] = [False]*(len(x)/2)
itertools.repeat
itertools.cycle
方法旨在无限地产生值。但是,您可以在
repeat()
上指定限制。像这样:

x[::2] = itertools.repeat(False, len(x)/2)

扩展切片赋值的右侧需要是大小合适的iterable(在本例中为10)

这是它的右边有一个常规列表:

>>> x = [True] * 20
>>> x[::2] = [False] * 10
>>> x
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]
这是itertools。在右边重复

>>> from itertools import repeat
>>> x = [True] * 20
>>> x[::2] = repeat(False, 10)
>>> x
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]

正如马克·托洛宁(Mark Tolonen)在一篇简洁的评论中指出的那样,itertools尝试无限期循环的原因是,对于列表赋值,python正在检查右侧的长度

>>> from itertools import repeat
>>> x = [True] * 20
>>> x[::2] = repeat(False, 10)
>>> x
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]
现在要真正深入研究

当你说:

x[::2] = itertools.repeat(False)
左侧(
x[::2]
)是一个列表,您正在为一个列表分配一个值,其中的值是
itertools。重复(False)
iterable,它将永远迭代,因为它没有给定长度(根据)

如果您深入研究cPython实现中的列表分配代码,您将发现不幸/痛苦地命名的函数,它是许多列表分配内容的根源。在该代码中,您将看到:

这里,它试图获取分配给列表的iterable的长度(
n
)。然而,甚至在到达那里之前,它就被卡住了,它最终尝试将您的iterable转换为一个列表(with),在其中它最终创建一个空列表,并尝试简单地用您的iterable扩展它

要使用iterable扩展列表,它使用,在这里您将看到问题的根源:

/* Run iterator to exhaustion. */
for (;;) {
就这样

或者至少我这么认为……:)这是一个有趣的问题,所以我想我会有一些乐趣,并通过挖掘源代码,看看发生了什么,并在那里结束

至于numpy数组的不同行为,这只是处理
numpy.array
赋值方式的不同

请注意,使用
itertools.repeat
在numpy中不起作用,但它不会挂断(我没有检查实现以找出原因):


这正是我想做的。我是从一个numpy用户的角度来看的。如果有
x=numpy.ones(10,dtype='bool')
x[::2]=False
将数组的第0,2,4,6,8个元素设置为False。我想知道,即使使用itertools,为什么列表的等效项也会失败。numPy通常会以与普通python不同的方式处理事情,这是有充分理由的,但在这种情况下,
x[::2]
返回一个大小为
x/2
的列表,其中包含
0,2,4,6,8…
th个元素。要以正常的python方式进行,请使用列表理解的flexability。为什么x[::2]无限地要求赋值?在我的原始示例中,只有10个元素需要赋值。为什么不对itertools调用设置限制?不,
repeat
products
/* Run iterator to exhaustion. */
for (;;) {
>>> import numpy, itertools
>>> x = numpy.ones(10,dtype='bool')
>>> x[::2] = itertools.repeat(False)
>>> x
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)
>>> #but the scalar assignment does work as advertised...
>>> x = numpy.ones(10,dtype='bool')
>>> x[::2] = False
>>> x
array([False,  True, False,  True, False,  True, False,  True, False,  True], dtype=bool)