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
4
  • 2
    This is quite hard to understand. What sequence of numbers do you want to generate via call_iter? Commented Mar 22, 2012 at 2:54
  • Does this have to use the callable form of iter? Is it the starting number you want to pass? Commented Mar 22, 2012 at 2:57
  • Perhaps a custom iterator? stackoverflow.com/questions/19151/build-a-basic-python-iterator Commented Mar 22, 2012 at 3:01
  • @AdamMihalcin I want to implement a iter, which takes its previous iter.next() return value as its argument of next iter.next(). Commented Mar 22, 2012 at 3:42

3 Answers 3

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
Sign up to request clarification or add additional context in comments.

8 Comments

But since the callable is returning a function, what purpose does the sentinel value of 100 serve?
@agf, i am still trying to guess that :)
My thought was he meant something like call_iter = iter(lambda x=itertools.count().next: x() + 1, 100) but who knows.
@agf, I thought something like that is really just an xrange
@agf, I wait with bated breath for the OP to clarify the question :)
|
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

Comments

-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]

1 Comment

I think you should use imap otherwise there is little sense using an iterator

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.