如何使用变量来切割Python列表?

时间:2015-09-03 12:57:10

标签: python list python-3.x syntax slice

我有六个项目的无害列表“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']

通过“轻松”,我的意思是例如不关心我的代码与列表的长度。

我了解到Python切片“总是退缩”(也称为“最多但不包括”)。我在我的图表中显示了这个“箭头”,从切片的末端指向前面的“下一个项目”(在切片的意义/方向上“向前”)。

对于我的用户,我需要显示列表中的第一个这么多项目。 (这些是递归搜索和评估和排序运行的结果。)因为通常这个列表相当长,我打印向后(在控制台中),这样当脚本结束时,屏幕上仍会显示最佳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转换为任何整数或其他数字。有办法吗?可能是Pythonland中的亵渎......

如果我找不到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(如when use negative number to slice a string in Python, 0 is disabled?)和在线(如https://docs.python.org/3/library/functions.html?highlight=slice#slice)上搜索并阅读了大量关于切片和变量的内容,并通过诸如Introducing Python和Learning Python等电子书进行了搜索。

请求:
请不要告诉我我想要的是错的。我可以对mylist[0:6:1]进行切片,但我的示例列表中没有索引6的项目,-7也是如此。这就是为什么我有这种预感,xy可能有数字,我可以在我的变量中使用。

欢迎您告诉我它不存在或不能以我喜欢的方式完成。在后一种情况下,我也要求你提供替代方案,尽可能接近我的要求。

那些想要更多的人的背景:
这个问题更多的是关于“搞清楚切片”而不是关于使打印输出成为可能。我确实有变通办法,但很想知道更多。

3 个答案:

答案 0 :(得分:4)

简短的回答是:

如果您不想计算列表的长度,则必须使用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']

可以使用占位符来&#34;整个事情&#34; ,例如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']

答案 1 :(得分:1)

只需设置默认值,如果用户更改默认值(最大值),则更改变量。

>>> 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']

我认为你的选项是无或列表的长度。

...或者只是使用try catch

>>> display_num = None
>>> try:
>>>     mylist[display_num-1::-1]
>>> except TypeError:
>>>     mylist[::-1]

答案 2 :(得分: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。为了做你想做的事,PySlice_GetIndicesEx必须设置 step = -1 start = 2 slicelength = 3 。< / p>

start = 2 step = -1 已由您的代码设置。 y 的值是否会导致 slicelength = 3 ?我们来看看......

步骤为负数时,计算 slicelength 的行为this one

*slicelength = (*stop-*start+1)/(*step)+1;

从这里,我们可以看到,为了让 slicelength =(停止 - 开始+ 1)/步骤+ 1 = 3 ,我们必须有 stop = -1 。但是,the case stop < 0 is treated specially

if (*stop < 0) *stop += length;
if (*stop < 0) *stop = (*step < 0) ? -1 : 0;

因此,如果我们提供否定停止,则会增加len(mylist)。如果 stop 仍为负数,则设置为 -1 ,这是我们需要的值。