Python 切片操作方法,我知道 Python 切片,但如何使用内置切片对象呢?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3911483/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:18:57  来源:igfitidea点击:

Python slice how-to, I know the Python slice but how can I use built-in slice object for it?

pythonslice

提问by necromancer

What's the use of built-in function sliceand how can I use it?
The direct way of Pythonic slicing I know - l1[start:stop:step]. I want to know if I have a slice object, then how do I use it?

内置函数有什么用,slice如何使用?
我知道的 Pythonic 切片的直接方式 - l1[start:stop:step]. 我想知道我是否有切片对象,那么我如何使用它?

采纳答案by PaulMcG

You create a slice by calling slice with the same fields you would use if doing [start:end:step] notation:

如果使用 [start:end:step] 表示法,您可以通过调用具有相同字段的切片来创建切片:

sl = slice(0,4)

To use the slice, just pass it as if it were the index into a list or string:

要使用切片,只需将它作为索引传递给列表或字符串:

>>> s = "ABCDEFGHIJKL"
>>> sl = slice(0,4)
>>> print(s[sl])
'ABCD'

Let's say you have a file of fixed-length text fields. You could define a list of slices to easily extract the values from each "record" in this file.

假设您有一个固定长度文本字段的文件。您可以定义一个切片列表,以便轻松地从此文件中的每个“记录”中提取值。

data = """\
0010GEORGE JETSON    12345 SPACESHIP ST   HOUSTON       TX
0020WILE E COYOTE    312 ACME BLVD        TUCSON        AZ
0030FRED FLINTSTONE  246 GRANITE LANE     BEDROCK       CA
0040JONNY QUEST      31416 SCIENCE AVE    PALO ALTO     CA""".splitlines()


fieldslices = [slice(*fielddef) for fielddef in [
    (0,4), (4, 21), (21,42), (42,56), (56,58),
    ]]
fields = "id name address city state".split()

for rec in data:
    for field,sl in zip(fields, fieldslices):
        print("{} : {}".format(field, rec[sl]))
    print('')

Prints:

印刷:

id : 0010
name : GEORGE JETSON    
address : 12345 SPACESHIP ST   
city : HOUSTON       
state : TX

id : 0020
name : WILE E COYOTE    
address : 312 ACME BLVD        
city : TUCSON        
state : AZ

id : 0030
name : FRED FLINTSTONE  
address : 246 GRANITE LANE     
city : BEDROCK       
state : CA

id : 0040
name : JONNY QUEST      
address : 31416 SCIENCE AVE    
city : PALO ALTO     
state : CA

回答by Tim McNamara

The slicefunction returns slice objects. Slice objects are one of Python's internal types, which are optimized for read performance - all of their attributes are read-only.

slice函数返回切片对象。Slice 对象是 Python 的内部类型之一,针对读取性能进行了优化——它们的所有属性都是只读的。

Altering slicecould be useful if wish to change the default behaviour. For example, lxmluses slice notation to access DOM elements (however, I haven't confirmed how they did that myself).

slice如果希望更改默认行为,更改可能很有用。例如,lxml使用切片表示法访问 DOM 元素(但是,我自己还没有确认他们是如何做到的)。

回答by Don O'Donnell

Square brackets following a sequence denote either indexing or slicing depending on what's inside the brackets:

序列后面的方括号表示索引或切片,具体取决于括号内的内容:

>>> "Python rocks"[1]    # index
'y'
>>> "Python rocks"[1:10:2]    # slice
'yhnrc'

Both of these cases are handled by the __getitem__()method of the sequence (or __setitem__()if on the left of an equals sign.) The index or slice is passed to the methods as a single argument, and the way Python does this is by converting the slice notation, (1:10:2, in this case) to a slice object: slice(1,10,2).

这两种情况都由__getitem__()序列的方法处理(或者__setitem__()如果在等号的左侧。)索引或切片作为单个参数传递给方法,Python 这样做的方式是通过转换切片表示法, ( 1:10:2, 在本例中) 到切片对象:slice(1,10,2).

So if you are defining your own sequence-like class or overriding the __getitem__or __setitem__or __delitem__methods of another class, you need to test the index argument to determine if it is an intor a slice, and process accordingly:

因此,如果您要定义自己的类似序列的类或覆盖另一个类的__getitem__or__setitem____delitem__方法,则需要测试 index 参数以确定它是 anint还是 a slice,并进行相应处理:

def __getitem__(self, index):
    if isinstance(index, int):
        ...    # process index as an integer
    elif isinstance(index, slice):
        start, stop, step = index.indices(len(self))    # index is a slice
        ...    # process slice
    else:
        raise TypeError("index must be int or slice")

A sliceobject has three attributes: start, stopand step, and one method: indices, which takes a single argument, the length of the object, and returns a 3-tuple: (start, stop, step).

一个slice对象具有三个属性:startstopstep,以及一个方法:indices,它接受一个参数,对象的长度,并返回一个三元组:(start, stop, step)

回答by SingleNegationElimination

>>> class sl:
...  def __getitem__(self, *keys): print keys
...     
>>> s = sl()
>>> s[1:3:5]
(slice(1, 3, 5),)
>>> s[1:2:3, 1, 4:5]
((slice(1, 2, 3), 1, slice(4, 5, None)),)
>>>

回答by Roman Susi

While trying to answer Subset a string based on variable, I recalled that numpy has a syntactically nice way to define slice objects:

在尝试回答Subset a string based on variable 时,我回想起 numpy 有一种语法上很好的方式来定义切片对象:

>>> import numpy as np
>>> s = "The long-string instrument is a musical instrument in which the string is of such a length that the fundamental transverse wave is below what a person can hear as a tone."
>>> z = np.s_[18:26]  # in this case same as slice(18, 26, None)
>>> s[z]
'strument'

The problem solved here is how to store the slice in a variable for later use, and np.s_allows to do just that. Yes, it's not built-in, but as that original question was redirected here I feel like my answer belong here as well. Also, numpy was one of the reasons why so advanced slicing abilities were added to Python, IIRC.

这里解决的问题是如何将切片存储在变量中供以后使用,并np.s_允许这样做。是的,它不是内置的,但是由于原始问题被重定向到这里,我觉得我的答案也属于这里。此外,numpy 是将如此先进的切片功能添加到 Python IIRC 的原因之一。

An example of a more complex "slicing":

一个更复杂的“切片”的例子:

>>> data = np.array(range(6)).reshape((2, 3))
>>> z = np.s_[:1, 1:2]
>>> data[z]
array([[1]])
>>> data
array([[0, 1, 2],
       [3, 4, 5]])
>>> z
(slice(None, 1, None), slice(1, 2, None))

where z is now a tuple of slices.

其中 z 现在是切片元组。