2

Python 2.6.2

>>> call_iter = iter(lambda x: x + 1, 100)
>>> call_iter.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes exactly 1 argument (0 given)

I want to pass argument to lambda x:x + 1.

Update: I think the example above is hard to understand.

I wonder whether there is a builtin func like myiter in python:

class myiter:
    def __init__(self, callable, initial, sentinel):
        self.value = initial
        self.callable = callable
        self.sentinel = sentinel

    def __iter__(self):
        return self

    def next(self):
        if self.value == self.sentinel:
            raise StopIteration
        else:
            # calculate next value from prev value
            self.value = self.callable(self.value) 
            return self.value

if __name__ == '__main__':
    call_iter = myiter(lambda x:x + 1, 0, 100)
    for i in call_iter:
        print i
xiaochen
  • 1,283
  • 2
  • 13
  • 30
  • 2
    This is quite hard to understand. What sequence of numbers do you want to generate via `call_iter`? – Adam Mihalcin Mar 22 '12 at 02:54
  • Does this have to use the callable form of `iter`? Is it the starting number you want to pass? – agf Mar 22 '12 at 02:57
  • Perhaps a custom iterator? http://stackoverflow.com/questions/19151/build-a-basic-python-iterator – Theron Luhn Mar 22 '12 at 03:01
  • @AdamMihalcin I want to implement a iter, which takes its previous iter.next() return value as its argument of next iter.next(). – xiaochen Mar 22 '12 at 03:42

3 Answers3

3

I'm not sure what you are trying to accomplish here, but

>>> call_iter = iter(lambda:lambda x: x + 1, 100)
>>> next(call_iter)(1)
2
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
1

The form of iter you're trying to use only takes a 0-argument function. The below is for illustration only; don't actually do this.

>>> x = 0
>>> def counter():
...     global x
...     x += 1
...     return x
... 
>>> list(iter(counter, 10))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

In general, this form of iter isn't very useful. It requires some kind of callable that maintains state between calls. So for example, you could pass the readline method of a file object, as suggested in the docs. But generally, there are better ways to do this. So for example, say you created a class like this:

>>> class Incrementer(object):
...     def __init__(self):
...         self.state = 0
...     def __call__(self):
...         rval = self.state
...         self.state += 1
...         return rval
... 
>>> list(iter(Incrementer(), 10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

It's lovely and all, but if you have to create a class that's supposed to be iterable, you might as well make it a real iterator by giving it a next method and an __iter__ method. Conversely, if you aren't creating a class, just use yield

Community
  • 1
  • 1
senderle
  • 145,869
  • 36
  • 209
  • 233
-1

i think what you want is:

call_iter = iter(map(lambda x: x + 1, range(100)))
>>> call_iter.next()
1
>>> call_iter.next()
2
>>> call_iter.next()
3
>>> 

to pass an argument to the lambda function you need to map the lambda to an iterable like range(100) or [2,4,5]

aschmid00
  • 7,038
  • 2
  • 47
  • 66