2009-03-25 50 views
5

Tôi muốn tạo đối tượng slice từ một chuỗi; ngay bây giờ, cách duy nhất có vẻ như thông qua một tuyên bố tội phạm rườm rà đánh giápython tạo đối tượng slice từ chuỗi

class getslice: 
    def __getitem__(self, idx): return idx[0] 
eval("getslice()[%s, 1]" %(":-1")) 

cảm ơn trước.

Chỉnh sửa: Xin lỗi nếu lời nhắc ban đầu không rõ ràng, đầu vào trong trường hợp này là ": -1". Vấn đề là phân tích chuỗi. Phản hồi của Ignacio Vazquez-Abrams ít nhất đã giải quyết vấn đề (và dường như cũng làm việc với chỉ mục ngược), nhưng tôi nghĩ giải pháp của tôi ở trên vẫn rõ ràng hơn nếu không làm sạch khái niệm (và sẽ hoạt động chính xác nếu Python thay đổi cú pháp cắt).

+0

Bạn có thể trở thành một chút rõ ràng hơn về hành vi bạn đang tìm kiếm? –

+0

-1: Tại sao bạn tạo một đối tượng slice độc ​​lập? Slices là các phần tử cú pháp hạng nhất? Nếu không có bất kỳ lý do gì về lý do tại sao bạn làm điều này, câu hỏi này rất kỳ quặc. –

+0

Jaffe: câu hỏi được cập nhật. Lott: Tôi đang làm một chút công việc ngôn ngữ, và cũng muốn sử dụng các lát Python. Các đối tượng thực sự là khá hữu ích: nó có một chỉ số (len) chức năng mà sẽ cung cấp cho một (bắt đầu, dừng lại, tăng) cho một chiều dài mảng – gatoatigrado

Trả lời

3
slice(*[{True: lambda n: None, False: int}[x == ''](x) for x in (mystring.split(':') + ['', '', ''])[:3]]) 
+7

điều này là sai, e. g. '1: 1: 1: 1' không phải là một chuỗi cắt chính xác và '1: 1: 1'. Nên thêm một cái gì đó như thế này: slice (* map (lambda x: int (x.strip()) nếu x.strip() else None, mystring.split (':'))) – pprzemek

+3

Plus nó thực sự là mã xấu. – Evpok

+1

pprzemek, bình luận của bạn chứa câu trả lời hay nhất theo ý kiến ​​của tôi, tại sao bạn không trả lời thực sự? –

4

Nếu bạn muốn có một đối tượng lát cắt, tại sao bạn không tạo một đối tượng?

s = slice(start, stop, step) 

Bạn có ý nghĩa gì khi "tạo chuỗi từ chuỗi"?

0

Đối tượng lát thường được tạo bằng ký hiệu chỉ số, ký hiệu này sử dụng slice() bên trong, như đã nêu trên slice() documentation. Những gì bạn muốn làm là:

your_string[start:end] 

Từ the python tutorial:

Strings có thể được subscripted (lập chỉ mục); như trong C, ký tự đầu tiên của chuỗi có chỉ số (chỉ mục) 0. Có không có loại ký tự riêng biệt; một ký tự chỉ đơn giản là một chuỗi có kích thước . Giống như trong Biểu tượng, các bản chất có thể là được chỉ định bằng ký hiệu cắt lát: hai chỉ số được phân tách bằng dấu hai chấm.

>>> word = 'Help' + 'A' 
>>> word[4] 
'A' 
>>> word[0:2] 
'He' 
>>> word[2:4] 
'lp' 

chỉ số Slice có giá trị mặc định hữu ích; một bỏ qua chỉ mục đầu tiên mặc định là 0, chỉ mục thứ hai bị bỏ qua mặc định là kích thước của chuỗi bị cắt.

>>> word[:2] # The first two characters 
'He' 
>>> word[2:] # Everything except the first two characters 
'lpA' 
+0

xin lỗi, đó không phải là những gì tôi đã hỏi, tôi muốn phân tích cú pháp, ví dụ: "-3 :: 2" từ một chuỗi và trả về một đối tượng slice [xem câu hỏi gốc]. – gatoatigrado

+0

Nó không rõ ràng từ câu hỏi của bạn rằng đó là những gì bạn đang yêu cầu. Tôi xin lỗi tôi không thể giúp bạn nữa, những gì tôi khuyên bạn nên đọc Zen của Python và xem xét lại nếu những gì bạn đang cố gắng làm không đi ngược lại, nếu nó có thể là một ý tưởng tồi. – mpeterson

+0

chắc chắn, tôi nghĩ rằng hầu hết các mã của tôi đáp ứng điều đó (cảm ơn cho ref). Tôi xin lỗi tôi không biết làm thế nào để làm rõ hơn; bạn đã đọc câu hỏi được sửa đổi (và bình luận dưới đây) chưa? liên quan, Nicholas – gatoatigrado

1

tôi kết thúc ở đây vì tôi muốn kịch bản của tôi để chấp nhận một đối số mối nối python-like và làm cho nó thành một danh sách các số nguyên, tôi đã làm nó với một chức năng mà có vẻ như nó trả lời câu hỏi OP của:

# create a slice object from a string 
def get_slice_obj(slicearg): 
    slice_ints = tuple([ int(n) for n in slicearg.split(':') ]) 
    return apply(slice, slice_ints) 

def ints_from_slicearg(slicearg): 
    slice_obj = get_slice_obj(slicearg) 
    return(range(slice_obj.start or 0, slice_obj.stop or -1, slice_obj.step or 1)) 

for t in ['1', '1:3', '4:9:2']: 
    print t, "=>", ints_from_slicearg(t) 

Output:

1 => [0] 
1:3 => [1, 2] 
4:9:2 => [4, 6, 8] 
0

Dựa trên @pprzema k soạn thảo các chức năng sau đây để phân tích công phu:

def parse_slice(v: Text): 
    """ 
    Parses text like python "slice" expression (ie ``-10::2``). 

    :param v: 
     the slice expression or a lone integer 
    :return: 
     - None if input is None/empty 
     - a ``slice()`` instance (even if input a lone numbrt) 
    :raise ValueError: 
     input non-empty but invalid syntax 
    """ 
    orig_v = v 
    v = v and v.strip() 
    if not v: 
     return 

    try: 
     if ':' not in v: 
      ## A lone number given. 
      v = int(v) 
      return slice(v, v + 1) 

     return slice(*map(lambda x: int(x.strip()) if x.strip() else None, 
          v.split(':'))) 
    except Exception: 
     pass 

    ## An alternative is to return `slice(None)` here. 
    raise trt.TraitError("Syntax-error in '%s' slice!" % orig_v) 
0

Đây là một phương pháp (chỉ là một tổng hợp của những người khác được đăng ở đây):

def make_slice(expr): 
    def to_piece(s): 
     return s and int(s) or None 
    pieces = map(to_piece, expr.split(':')) 
    if len(pieces) == 1: 
     return slice(pieces[0], pieces[0] + 1) 
    else: 
     return slice(*pieces) 

Ví dụ cách dùng:

In [1]: make_slice(':') 
Out[1]: slice(None, None, None) 

In [2]: make_slice(':-2') 
Out[2]: slice(None, -2, None) 

In [3]: x = [1, 2, 3] 

In [4]: x[make_slice('::-1')] 
Out[4]: [3, 2, 1] 
Các vấn đề liên quan