Đối tượng là vô số nhưng không thể lập chỉ mục?


10

Tóm tắt vấn đề và câu hỏi

Tôi đang cố gắng xem xét một số dữ liệu bên trong một đối tượng có thể được liệt kê nhưng không được lập chỉ mục. Tôi vẫn còn mới với trăn, nhưng tôi không hiểu làm thế nào điều này là có thể.

Nếu bạn có thể liệt kê nó, tại sao bạn không thể truy cập chỉ mục thông qua cách liệt kê tương tự? Và nếu không, có cách nào để truy cập các mục riêng lẻ không?

Ví dụ thực tế

import tensorflow_datasets as tfds

train_validation_split = tfds.Split.TRAIN.subsplit([6, 4])

(train_data, validation_data), test_data = tfds.load(
    name="imdb_reviews", 
    split=(train_validation_split, tfds.Split.TEST),
    as_supervised=True)

Lấy một tập hợp con của tập dữ liệu

foo = train_data.take(5)

Tôi có thể lặp đi lặp lại foovới liệt kê:

[In] for i, x in enumerate(foo):
    print(i)

tạo ra sản lượng dự kiến:

0
1
2
3
4

Nhưng sau đó, khi tôi cố gắng lập chỉ mục vào nó, foo[0]tôi gặp lỗi này:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-2acbea6d9862> in <module>
----> 1 foo[0]

TypeError: 'TakeDataset' object does not support indexing

1
Bởi vì liệt kê không truy cập vào một chỉ mục. Không có khái niệm "vô số" trong trăn, nó chỉ đơn thuần là lặp đi lặp lại
juanpa.arrivillaga

Câu trả lời:


6

Python chỉ cho phép những thứ này nếu lớp có các phương thức cho chúng:

Bất kỳ lớp nào có thể định nghĩa cái này mà không định nghĩa cái kia. __getattr__thường không được xác định nếu nó sẽ không hiệu quả.


1 __next__ là bắt buộc trên lớp trả về __iter__.


1

Đây là kết quả của fooviệc lặp lại, nhưng không có __getitem__chức năng. Bạn có thể sử dụng itertools.issliceđể có được phần tử thứ n của một lần lặp như vậy

import itertools

def nth(iterable, n, default=None):
    "Returns the nth item or a default value"
    return next(itertools.islice(iterable, n, None), default)

0

Trong Python, các thể hiện của các lớp tùy chỉnh có thể thực hiện phép liệt kê thông qua phương thức đặc biệt (hoặc "dunder") __iter__. Có lẽ lớp này thực hiện __iter__nhưng không__getitem__ .

Tổng quan về Dunder: https://dbader.org/blog/python-dunder-methods
Thông số kỹ thuật cho một __iter__phương thức: https://docs.python.org/3/l Library / stdtypes.html#typeiter


1
Không phải "liệt kê" thay vì "lặp lại"
juanpa.arrivillaga
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.