Самый чистый способ получить последний объект от итератора Python

Что лучший способ добраться последний объект от итератора в Python 2.6? Например, сказать

my_iter = iter(range(5))

Каков самый короткий код / самый чистый способ добраться 4 от my_iter?

Я мог сделать это, но это не кажется очень эффективным:

[x for x in my_iter][-1]
102
задан DhiaTN 5 March 2018 в 19:11
поделиться

7 ответов

Процесс скрытия сведений о реализации называется Инкапсуляция . Процесс минимизации зависимостей сборки для пользователей называется Изоляция . Существует большая (но стареющая) книга Джона Лакоса, посвященная обеим темам:

http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620

-121--4293897-

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

<xs:schema targetNamespace="http://yourcompany/yourapp/1.0" ... >
  ...
</xs:schema>

В качестве примера посмотрите на xsd, определенные w3.org, вот как они это делают. Обратите внимание, что изменение номера версии, как правило, по определению является прерывистым изменением для любых потребителей xsd (независимо от того, насколько маленьким было фактическое изменение или какая часть номера версии была изменена).

Для уменьшения влияния на управление версиями существует договоренность о размещении атрибута версии в корневом элементе:

<xs:schema version="1.0.0" ...>
  ...
</xs:schema>
-121--1667127-
item = defaultvalue
for item in my_iter:
    pass
90
ответ дан 24 November 2019 в 04:27
поделиться

Если необходимо скомпилировать сопоставление времени, можно использовать следующий шаблон:

// template to specialize
template<int T> struct int2int {};    

// macro for simplifying declaration of specializations
#define I2I_DEF(x, v) template<> struct int2int<x> { static const int value = v; };

// definitions
I2I_DEF(2, 5) I2I_DEF(79, 12958) I2I_DEF(55, 100) // etc.

// use
#include <iostream>    
int main()
{
  std::cout << int2int<2>::value << " " << int2int<79>::value << std::endl;

  return 0;
}
-121--4089968-
item = defaultvalue
for item in my_iter:
    pass
-121--755697-

Я бы использовал обратный , за исключением того, что он принимает только последовательности вместо итераторов, что кажется довольно произвольным.

Как бы вы ни делали это, вам придется пройти через весь итератор. При максимальной эффективности, если вам больше не нужен итератор, вы можете просто выбросить все значения:

for last in my_iter:
    pass
# last is now the last item

Я думаю, что это неоптимальное решение.

5
ответ дан 24 November 2019 в 04:27
поделиться

Это вряд ли будет быстрее, чем пустые для петли из-за лямбда, но, возможно, он даст кому-то еще идею

reduce(lambda x,y:y,my_iter)

, если ивес пуст, тип эпицентризации

19
ответ дан 24 November 2019 в 04:27
поделиться

Там это

list( the_iter )[-1]

, если длина итерации действительно Epic - так долго, что материализуя список выхлопной памяти - тогда вам действительно нужно переосмыслить дизайн.

9
ответ дан 24 November 2019 в 04:27
поделиться

Вероятно, стоит использовать __reververed__, если она доступна

if hasattr(my_iter,'__reversed__'):
    last = next(reversed(my_iter))
else:
    for last in my_iter:
        pass
32
ответ дан 24 November 2019 в 04:27
поделиться

Вопрос некорректен и может привести только к сложному и неэффективному ответу. Чтобы получить итератор, вы, конечно, начинаете с чего-то, что является итерируемым, что в большинстве случаев предлагает более прямой способ доступа к последнему элементу.

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

Таким образом, наиболее эффективный и понятный способ - не создавать итератор в первую очередь, а использовать собственные методы доступа итерабельной таблицы.

-6
ответ дан 24 November 2019 в 04:27
поделиться

Использовать deque размера 1.

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()
58
ответ дан 24 November 2019 в 04:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: