如何使用变量对 Python 列表进行切片?
How to use variables for slicing Python lists?
我有一份包含六项的无害清单 "mylist"。永远不会空着,永远不会有任何野兽般的物品。
mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff']
我发现有两种方法可以为切片索引列表。对于这个问题,我将它们称为上索引(从0到5)和下索引(从-1到-6)。这是一个快速图表(我发布了一张带颜色的照片,被另一个用户替换):
<<<<|_________mylist[5:?:-1]_____________|
|___mylist[0:3:1]______|>>>>>>
?
(x) 0 1 2 3 4 5 (6)
aaa bbb ccc ddd eee fff
(-7) -6 -5 -4 -3 -2 -1 (y)
?
<<<<<<|___mylist[-1:-5:-1]___|
|______mylist[-6:?:1]________________|>>>>>
为了在列表的开头轻松切片,我可以像这样使用上索引:
>>> mylist[0:3:1]
['aaa', 'bbb', 'ccc']
为了在结尾附近轻松切片,我发现较低的索引很有用,例如:
>>> mylist[-1:-5:-1]
['fff', 'eee', 'ddd', 'ccc']
"easily" 我的意思是例如不考虑我的代码与列表长度的方面。
了解到Python分片是"always holding back"(又名"up to but not including")。我在我的图表中将其显示为 "arrow-heads" 从切片的末尾指向前面的 "next item"(切片的 sense/direction 中的 "ahead")。
对于我的用户,我需要显示列表中的前这么多项目。 (这些是递归搜索、评估和排序 运行 的结果。)因为通常这个列表很长,所以我将它打印 backwards (在控制台中),所以当脚本结束时,最好的 n
结果仍会显示在屏幕上。所以我的步骤是 -1
在这种情况下。
我想使用变量来满足不同用户(和不同屏幕尺寸)的不同需求。 对于调试和某些用户,我希望能够打印所有结果,即向后打印整个列表。我想要这种语法中的内容:
start = 5 # I only need to know "5" for debugging, normally I can use
# any small number to show a few selected items of mylist
end = x # this is my main question, see photo
mylist[start:end:-1]
我的问题是,如何在图中写第一个(最上面的)切片,通过使用变量和通过使用索引的上层列表? 或者换句话说,x
(和y
)的数值是多少在图中?
我不想使用的半解决方案:
mylist[5::-1] # no variable at all
mylist[5:None:-1] # does not fit in my normal function for printing
我没有设法在任何简单的变量操作中使用 None
,它给我这样的错误:
end = None - 20
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
而且我还没有设法将 None
转换为任何整数或其他数字。有办法吗?在 Python 土地上可能是一种亵渎...
如果我找不到x
的秘密号码,那么我可能需要使用这个:
mylist[-1:-7:-1] # I want to use the upper index rather
但这种方法涉及检查 mystring
的长度。
end = -1 * (len(mystring)+1) # extra-explicit as an example
returns -7
mystring[-1:end:-1]
returns ['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa'] # this is the output I want, just not the method
问你之前我做了什么:
我写了一个测试脚本并尝试猜测 x
。我在 Stack Overflow 上搜索并阅读了大量关于切片和变量的内容(比如 ) and online (like https://docs.python.org/3/library/functions.html?highlight=slice#slice),我还搜索了电子书,比如 Introducing Python 和 Learning Python.
请求:
请不要告诉我我想要的是错误的。尽管在我的示例列表中没有索引为 6
的项目,但我可以对 mylist[0:6:1]
进行切片,-7
也是如此。这就是为什么我有这种预感,可能会有 x
和 y
的数字,我可以在我的变量中使用它们。
欢迎您告诉我它不存在或无法按照我希望的方式完成。在后一种情况下,我还要求您提供尽可能接近我的要求的替代方案。
想要更多的背景:
这个问题更多的是关于 "figuring out slicing" 而不是关于使打印输出成为可能。我确实有解决方法,但很想了解更多。
简短的回答是:否。
如果你不想计算列表的长度,你必须使用None
(虽然这是Python中的O(1)
操作):
>>> mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff']
>>> mylist[2:None:-1] # first 3 items backwards (note off-by-one indexing)
['ccc', 'bbb', 'aaa']
>>> mylist[None:None:-1] # all items backwards
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa']
您可以为"the whole thing"使用占位符,例如0
:
>>> end = 3
>>> mylist[end - 1 if end else None::-1]
['ccc', 'bbb', 'aaa']
>>> end = 0
>>> mylist[end - 1 if end else None::-1]
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa']
你也可以考虑两个步骤,即取你想要的切片然后反转它:
>>> mylist[:3][::-1]
['ccc', 'bbb', 'aaa']
只需设置一个默认值,如果用户更改默认值 (max),则更改您的变量。
>>> mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff']
>>> display_num = len(mylist)
>>> mylist[display_num-1::-1]
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa']
将 display_num 变量更改为您要显示的结果数。
>>> display_num = 4
>>> mylist[display_num-1::-1]
['ddd', 'ccc', 'bbb', 'aaa']
我认为你的选择是 None 或列表的长度。
... 或者只使用 try catch
>>> display_num = None
>>> try:
>>> mylist[display_num-1::-1]
>>> except TypeError:
>>> mylist[::-1]
如果我没有正确理解你的问题,你希望 y 这样
mylist[2:y:-1] == ['ccc', 'bbb', 'aaa']
其中 y 必须是整数。
您要查找的 y 是 -len(mylist)-1
或更小的整数。如果你需要一个常量,你可以使用 -sys.maxsize
(因为不可能有大于 maxsize
的列表)。
如果我们查看CPython的源代码,我们可以看到list
objects internally use the function PySlice_GetIndicesEx
. In order to do what you want, PySlice_GetIndicesEx
必须设置step = -1,start = 2 和 slicelength = 3.
start = 2 和 step = -1 已由您的代码设置。 y 的值是否可以导致 slicelength = 3?让我们看看...
当step为负数时,计算slicelength的行为this one:
*slicelength = (*stop-*start+1)/(*step)+1;
从这里我们可以看出,为了slicelength = (stop - start + 1) / step + 1 = 3,我们必须有停止 = -1。但是,the case stop < 0 is treated specially:
if (*stop < 0) *stop += length;
if (*stop < 0) *stop = (*step < 0) ? -1 : 0;
因此,如果我们提供负值 stop,它会增加 len(mylist)
。如果 stop 仍然是负数,它被设置为 -1,这是我们需要的值。
我有一份包含六项的无害清单 "mylist"。永远不会空着,永远不会有任何野兽般的物品。
mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff']
我发现有两种方法可以为切片索引列表。对于这个问题,我将它们称为上索引(从0到5)和下索引(从-1到-6)。这是一个快速图表(我发布了一张带颜色的照片,被另一个用户替换):
<<<<|_________mylist[5:?:-1]_____________|
|___mylist[0:3:1]______|>>>>>>
?
(x) 0 1 2 3 4 5 (6)
aaa bbb ccc ddd eee fff
(-7) -6 -5 -4 -3 -2 -1 (y)
?
<<<<<<|___mylist[-1:-5:-1]___|
|______mylist[-6:?:1]________________|>>>>>
为了在列表的开头轻松切片,我可以像这样使用上索引:
>>> mylist[0:3:1]
['aaa', 'bbb', 'ccc']
为了在结尾附近轻松切片,我发现较低的索引很有用,例如:
>>> mylist[-1:-5:-1]
['fff', 'eee', 'ddd', 'ccc']
"easily" 我的意思是例如不考虑我的代码与列表长度的方面。
了解到Python分片是"always holding back"(又名"up to but not including")。我在我的图表中将其显示为 "arrow-heads" 从切片的末尾指向前面的 "next item"(切片的 sense/direction 中的 "ahead")。
对于我的用户,我需要显示列表中的前这么多项目。 (这些是递归搜索、评估和排序 运行 的结果。)因为通常这个列表很长,所以我将它打印 backwards (在控制台中),所以当脚本结束时,最好的 n
结果仍会显示在屏幕上。所以我的步骤是 -1
在这种情况下。
我想使用变量来满足不同用户(和不同屏幕尺寸)的不同需求。 对于调试和某些用户,我希望能够打印所有结果,即向后打印整个列表。我想要这种语法中的内容:
start = 5 # I only need to know "5" for debugging, normally I can use
# any small number to show a few selected items of mylist
end = x # this is my main question, see photo
mylist[start:end:-1]
我的问题是,如何在图中写第一个(最上面的)切片,通过使用变量和通过使用索引的上层列表? 或者换句话说,x
(和y
)的数值是多少在图中?
我不想使用的半解决方案:
mylist[5::-1] # no variable at all
mylist[5:None:-1] # does not fit in my normal function for printing
我没有设法在任何简单的变量操作中使用 None
,它给我这样的错误:
end = None - 20
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
而且我还没有设法将 None
转换为任何整数或其他数字。有办法吗?在 Python 土地上可能是一种亵渎...
如果我找不到x
的秘密号码,那么我可能需要使用这个:
mylist[-1:-7:-1] # I want to use the upper index rather
但这种方法涉及检查 mystring
的长度。
end = -1 * (len(mystring)+1) # extra-explicit as an example
returns -7
mystring[-1:end:-1]
returns ['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa'] # this is the output I want, just not the method
问你之前我做了什么:
我写了一个测试脚本并尝试猜测 x
。我在 Stack Overflow 上搜索并阅读了大量关于切片和变量的内容(比如
请求:
请不要告诉我我想要的是错误的。尽管在我的示例列表中没有索引为 6
的项目,但我可以对 mylist[0:6:1]
进行切片,-7
也是如此。这就是为什么我有这种预感,可能会有 x
和 y
的数字,我可以在我的变量中使用它们。
欢迎您告诉我它不存在或无法按照我希望的方式完成。在后一种情况下,我还要求您提供尽可能接近我的要求的替代方案。
想要更多的背景:
这个问题更多的是关于 "figuring out slicing" 而不是关于使打印输出成为可能。我确实有解决方法,但很想了解更多。
简短的回答是:否。
如果你不想计算列表的长度,你必须使用None
(虽然这是Python中的O(1)
操作):
>>> mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff']
>>> mylist[2:None:-1] # first 3 items backwards (note off-by-one indexing)
['ccc', 'bbb', 'aaa']
>>> mylist[None:None:-1] # all items backwards
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa']
您可以为"the whole thing"使用占位符,例如0
:
>>> end = 3
>>> mylist[end - 1 if end else None::-1]
['ccc', 'bbb', 'aaa']
>>> end = 0
>>> mylist[end - 1 if end else None::-1]
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa']
你也可以考虑两个步骤,即取你想要的切片然后反转它:
>>> mylist[:3][::-1]
['ccc', 'bbb', 'aaa']
只需设置一个默认值,如果用户更改默认值 (max),则更改您的变量。
>>> mylist = ['aaa', 'bbb', 'ccc', 'ddd', 'eee', 'fff']
>>> display_num = len(mylist)
>>> mylist[display_num-1::-1]
['fff', 'eee', 'ddd', 'ccc', 'bbb', 'aaa']
将 display_num 变量更改为您要显示的结果数。
>>> display_num = 4
>>> mylist[display_num-1::-1]
['ddd', 'ccc', 'bbb', 'aaa']
我认为你的选择是 None 或列表的长度。
... 或者只使用 try catch
>>> display_num = None
>>> try:
>>> mylist[display_num-1::-1]
>>> except TypeError:
>>> mylist[::-1]
如果我没有正确理解你的问题,你希望 y 这样
mylist[2:y:-1] == ['ccc', 'bbb', 'aaa']
其中 y 必须是整数。
您要查找的 y 是 -len(mylist)-1
或更小的整数。如果你需要一个常量,你可以使用 -sys.maxsize
(因为不可能有大于 maxsize
的列表)。
如果我们查看CPython的源代码,我们可以看到list
objects internally use the function PySlice_GetIndicesEx
. In order to do what you want, PySlice_GetIndicesEx
必须设置step = -1,start = 2 和 slicelength = 3.
start = 2 和 step = -1 已由您的代码设置。 y 的值是否可以导致 slicelength = 3?让我们看看...
当step为负数时,计算slicelength的行为this one:
*slicelength = (*stop-*start+1)/(*step)+1;
从这里我们可以看出,为了slicelength = (stop - start + 1) / step + 1 = 3,我们必须有停止 = -1。但是,the case stop < 0 is treated specially:
if (*stop < 0) *stop += length;
if (*stop < 0) *stop = (*step < 0) ? -1 : 0;
因此,如果我们提供负值 stop,它会增加 len(mylist)
。如果 stop 仍然是负数,它被设置为 -1,这是我们需要的值。