6

I received this exercise:

Write a function enumerate that takes a list and returns a list of tuples containing (index,item) for each item in the list

My problem is that I cannot insert the index and value in one or a combination of for loops. This is the code I managed to make:

a = ["a", "b", "c","a","b","c"]
index = 0
for i in a:
    print (index,i)
    index+=1

This is roughly the code I want to produce (must be on one line):

my_enumerate = lambda x :[(t) for t in x )]
print list(my_enumerate(range(4)))

How can I put it all one lambda line to get (value, index) back? The output should look like:

[(0, "a"), (1, "b"), (2, "c")]
3
  • looks like it should return a dictionary with index as key. Commented May 18, 2015 at 12:47
  • 1
    Am I missing something or are you trying to reinvent the enumerate() function? Commented May 18, 2015 at 12:49
  • Or, if it has to be a lambda: my_enumerate = lambda L: list(ind,item for ind,item in enumerate(L)) Commented May 18, 2015 at 13:33

5 Answers 5

5

If you can actually index just add the value by indexing:

my_enumerate = lambda x :[(t, x[t]) for t in range(len(x))]
print list(my_enumerate(a))
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'a'), (4, 'b'), (5, 'c')]

If not use zip and put range in the lambda:

my_enumerate = lambda x: zip(range(len(x), x))
print list(my_enumerate(a))
Sign up to request clarification or add additional context in comments.

3 Comments

Your two examples seem quite different - the first expects the length of the list (and the list itself should also be in scope) and the second the list itself. Why not lambda a: [(t, a[t]) for t in range(len(a))]?
@jonrsharpe, pasted the wrong code. Actually irrelevant as the OP cannot index
I read that as meaning that they were unable to do so, rather than prohibited from it; you may well be right.
1
[(i,a[i])for i in range(len(a))]

Comments

0
my_enumerate = lambda x: [(i, x[i]) for i in xrange(len(x))]
a = ["a", "b", "c", "a", "b", "c"]
print my_enumerate(a)

outputs:

[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'a'), (4, 'b'), (5, 'c')]

EDIT: use range instead of xrange and print(...) instead of print if you are using python3

1 Comment

@H_meir, I thought you said you cannot index?
0

Python's zip and range functions solve this problem pretty handily.

my_enumerate = lambda seq: zip(range(len(seq)), seq)

In Python 2.x, you should use itertools.izip, and xrange instead.

Comments

0

You could also do it recursively:

>>> myenumerate = lambda l, n=0: [] if not l else (lambda ll = list(l): [(n, ll.pop(0))] + myenumerate(ll, n+1)()

list.pop(n) returns the nth value form the list, and returns it.

The only problem is that you must pass in a list:

>>> myenumerate([1,2,3,4,5,6,7,8])
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 8)]
>>> myenumerate("astring")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
AttributeError: 'str' object has no attribute 'pop'
>>> myenumerate(list("astring"))
[(0, 'a'), (1, 's'), (2, 't'), (3, 'r'), (4, 'i'), (5, 'n'), (6, 'g')]

However, if you just blindly added calls to list, you would't be able to replicate the functionality required without using a slice.

A neat trick for bypassing this requirement is to use another lambda:

>>> myenumerate = lambda l, n=0: [] if not l else (lambda ll: [(n, ll.pop(0))] + myenumerate(ll, n+1))(list(l))

>>> myenumerate("astring")
[(0, 'a'), (1, 's'), (2, 't'), (3, 'r'), (4, 'i'), (5, 'n'), (6, 'g')]

Comments

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.