Вопрос: Просмотры в Python3.1?


Что такое представления в Python3.1? Они, похоже, ведут себя так же, как и итераторы, и они также могут быть реализованы в списках. Как отличаются итераторы и взгляды?


18


источник


Ответы:


Из того, что я могу сказать, все еще привязано к объекту, из которого он был создан. Модификации исходного объекта влияют на представление.

из документы  (для просмотра словарей):

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()

>>> # iteration
>>> n = 0
>>> for val in values:
...     n += val
>>> print(n)
504

>>> # keys and values are iterated over in the same order
>>> list(keys)
['eggs', 'bacon', 'sausage', 'spam']
>>> list(values)
[2, 1, 1, 500]

>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> del dishes['sausage']
>>> list(keys)
['spam', 'bacon']

>>> # set operations
>>> keys & {'eggs', 'bacon', 'salad'}
{'bacon'}

12



Я бы рекомендовал вам прочитать это , Кажется, он лучше всего объясняет.

Насколько я могу судить, взгляды, похоже, больше связаны с dicts и может быть принудительно lists. Вы также можете сделать из него итератор, через который вы могли бы затем перебирать (в for цикла или путем вызова next)

Обновить: обновленная ссылка от машины обратного пути


5



Как отличаются итераторы и взгляды?

Я перефразирую вопрос как «какая разница между итерируемый  объектов и итератор «?

итерируемый  является объектом, который может быть повторен (например, использован в for петля).

итератор  является объектом, который можно вызвать с помощью next() функции, то есть реализует .next() метода в Python2 и .__next__() в python3. Итератор часто используется для итерируемый  и вернуть каждый интересующий объект. Все итераторы повторяемы, но обратное не обязательно верно (все итерации не являются итераторами).

Просмотры итерируемый  объектов, а не итераторы ,

Давайте посмотрим на некоторый код, чтобы увидеть различие (Python 3):

«Что нового в Python 3»  документ очень специфичен в отношении того, какие функции возвращают итераторы. map(), filter(), а также zip() определенно верните итератор, тогда как dict.items(), dict.values(), dict.keys() говорят, что возвращают объект вида. Что касается range(), хотя описание того, что он возвращает, точно не соответствует точности, мы знаем, что это не итератор.

С помощью map() удвоить все числа в списке

m = map(lambda x: x*2, [0,1,2])
hasattr(m, '__next__')
# True
next(m)
# 0
next(m)
# 2
next(m)
# 4
next(m)
# StopIteration ...

С помощью filter() извлечь все нечетные числа

f = filter(lambda x: x%2==1, [0,1,2,3,4,5,6])
hasattr(f, '__next__')
# True
next(f)
# 1
next(f)
# 3
next(f)
# 5
next(f)
# StopIteration ...

Попытка использовать range() таким же образом, чтобы получить последовательность чисел

r = range(3) 
hasattr(r, '__next__')
# False
next(r)
# TypeError: 'range' object is not an iterator

Но это итерабельно, поэтому мы должны иметь возможность обернуть его итератором

it = iter(r)
next(it)
# 0
next(it)
# 1
next(it)
# 2
next(it)
# StopIteration ...

dict.items() так же как dict.keys() а также dict.values() также не возвращать итераторы в Python 3

d = {'a': 0, 'b': 1, 'c': 2}
items = d.items()
hasattr(items, '__next__')
# False
it = iter(items)
next(it)
# ('b', 1)
next(it)
# ('c', 2)
next(it)
# ('a', 0)

Итератор может использоваться только в одном for цикл, тогда как итеративный может использоваться повторно в последующих for петли. Каждый раз, когда итерабельность используется в этом контексте, он неявно возвращает новый итератор (из его __iter__() метод). Следующий пользовательский класс демонстрирует это путем вывода памяти id как объекта списка, так и возвращаемого объекта итератора:

class mylist(list):
    def __iter__(self, *a, **kw):
        print('id of iterable is still:', id(self))
        rv = super().__iter__(*a, **kw)
        print('id of iterator is now:', id(rv))
        return rv 

l = mylist('abc')

for loop может использовать итерируемый объект и неявно получит итератор

for c in l:
    print(c)
# id of iterable is still: 139696242511768
# id of iterator is now: 139696242308880
# a
# b
# c

Последующее for loop может использовать один и тот же объект, но получит другой итератор

for c in l:
    print(c)
# id of iterable is still: 139696242511768
# id of iterator is now: 139696242445616
# a
# b
# c

Мы также можем получить итератор явно

it = iter(l)
# id of iterable is still: 139696242511768
# id of iterator is now: 139696242463688

но его можно использовать только один раз

for c in it:
    print(c)
# a
# b
# c
for c in it:
    print(c)
for c in it:
    print(c)

1