Хотя старый вопрос, но может быть, это может быть полезно кому-то.
Я использую этот способ преобразования строки в int number
var str = "25"; // string
var number = str*1; // number
Итак, при умножении на 1 , значение не изменяется, но js автоматически возвращает число.
Но, как показано ниже, это следует использовать, если вы уверены, что str
является числом (или может быть представлено как число), в противном случае оно вернет NaN - не число.
вы можете создать простую функцию для использования, например
function toNumber(str) {
return str*1;
}
[/g0]
import itertools
class Indexable(object):
def __init__(self,it):
self.it = iter(it)
def __iter__(self):
return self.it
def __getitem__(self,index):
try:
return next(itertools.islice(self.it,index,index+1))
except TypeError:
return list(itertools.islice(self.it,index.start,index.stop,index.step))
Вы можете использовать его следующим образом:
it = Indexable(fib())
print(it[10])
#144
print(it[2:12:2])
#[610, 1597, 4181, 10946, 28657]
Обратите внимание, что it[2:12:2]
не возвращает [3, 8, 21, 55, 144]
, поскольку итератор уже продвинулся на 11 элементов из-за вызова it[10]
.
Edit: Если вы хотите, чтобы it[2:12:2]
возвращал [3, 8, 21, 55, 144]
, то, возможно, вместо этого используйте следующее:
class Indexable(object):
def __init__(self, it):
self.it = iter(it)
self.already_computed = []
def __iter__(self):
for elt in self.it:
self.already_computed.append(elt)
yield elt
def __getitem__(self, index):
try:
max_idx = index.stop
except AttributeError:
max_idx = index
n = max_idx - len(self.already_computed) + 1
if n > 0:
self.already_computed.extend(itertools.islice(self.it, n))
return self.already_computed[index]
Эта версия сохраняет результаты в self.already_computed
и использует эти результаты, если это возможно.
если это возможно. В противном случае, он вычисляет больше результатов, пока их не будет достаточно много.
чтобы вернуть индексированный элемент или фрагмент.
Так что, основываясь на коде из ~ unutbu и добавив немного itertools.tee:
import itertools
class Indexable(object):
def __init__(self, it):
self.it = it
def __iter__(self):
self.it, cpy = itertools.tee(self.it)
return cpy
def __getitem__(self, index):
self.it, cpy = itertools.tee(self.it)
if type(index) is slice:
return list(itertools.islice(cpy, index.start, index.stop, index.step))
else:
return next(itertools.islice(cpy, index, index+1))
Вот ответ ~ unutbu, измененный для списка подклассов. Очевидно, такие злоупотребления, как append
, insert
и т. Д., Приведут к странным результатам!
вы получаете методы __ str __
и __ repr __
бесплатно, хотя
import itertools
class Indexable(list):
def __init__(self,it):
self.it=it
def __iter__(self):
for elt in self.it:
yield elt
def __getitem__(self,index):
try:
max_idx=index.stop
except AttributeError:
max_idx=index
while max_idx>=len(self):
self.append(next(self.it))
return list.__getitem__(self,index)
Если это одноразовый срез, вы можете просто использовать метод, написанный ~ unutbu. Если вам нужно нарезать несколько раз, вам придется сохранить все промежуточные значения, чтобы вы могли «перемотать» итератор. Поскольку итераторы могут выполнять итерацию чего угодно, по умолчанию у них не будет метода перемотки.
Кроме того, поскольку итератор перемотки должен сохранять каждый промежуточный результат, он (в большинстве случаев) не имеет преимуществ перед простым выполнением списка (итератор)
В принципе ... вам либо итератор не нужен , или вы недостаточно конкретны в отношении ситуации.