-1

i want to do a simple list manipulation in python: here is the way i did it using two for loops:

lst = []
coins = [1, 2, 5, 10, 20, 50, 100, 200]
maxi = 200
lst = lst + [0]*(maxi+5)
lst[0] = 1

for c in coins:
    for i in range(c, maxi+2):
        lst[i] += lst[i-c]

the above code gives me desired results, now i try to convert the two line loop into a one-liner

add = lambda i, c: lst[i] += lst[i-c]
[add(i, c) for i in range(c, maxi+1) for c in coins]

but i am getting an invalid syntax error, how can i pass the two variables c and i to lambda and then manipulate the list at the two indexes.

Which is a more pythonic way of doing it?

Can anyone suggest shorter code?

I want to use only list comprehension. How can i implement the above code using list comprehension?

user993563
  • 18,601
  • 10
  • 42
  • 55
  • Python lambdas only support expressions that return a result. `lst[i] += lst[i-c]` is a statement (with a side effect) but not an expression, so that's why you're getting a syntax error. – malloc47 Feb 17 '12 at 16:47
  • is there any way i could do with only the list comprehension?? – user993563 Feb 17 '12 at 16:50
  • List comprehension will most likely be slower than your nested loops? Why are you doing this? – John La Rooy Feb 17 '12 at 16:55
  • user993563: @SvenMarnach's answer does give a way to solve the problem using a list comprehension. However, he is entirely right that it is unnecessary and unpythonic. – David Robinson Feb 17 '12 at 16:56
  • @gnibbler i am doing it for fun, how much slower some 10 microseconds, i dont give a damn about microseconds. – user993563 Feb 17 '12 at 16:59
  • @DavidRobinson: where could i find the definition of "Pythonic"?? – user993563 Feb 17 '12 at 17:00
  • for definition of Pythonic `import this` – John La Rooy Feb 17 '12 at 17:03
  • 3
    Setting aside questions of pythonicity, the purpose of list comprehensions is to create lists. Using them as a flow control structure is a) confusing, b) contrary to their declarative nature, and c) wasteful of resources. – senderle Feb 17 '12 at 17:13
  • @gnibbler the clauses are subjective. I go by the first clause: Beautiful is better than ugly. List comprehensions are more b'ful to me than two ugly loops. – user993563 Feb 17 '12 at 17:32
  • It's your code. But if you think a for loop is "ugly", you're misunderstanding the doctrine. – David Robinson Feb 17 '12 at 18:15
  • 1
    Actually, there is an excellent StackOverflow question on precisely this question: http://stackoverflow.com/questions/5753597/is-it-pythonic-to-use-list-comprehensions-for-just-side-effects – David Robinson Feb 17 '12 at 18:16
  • 1
    @DavidRobinson thnx, i was a newbie, amazd by more complicated looking comprehension, that post explains stuff. – user993563 Feb 20 '12 at 12:36
  • @user993563: indeed, we all start as beginners, and we've all been there :-) – David Robinson Feb 20 '12 at 17:19

3 Answers3

6

I think the double loop you have is perfectly fine -- why do you want a shorter version?

The error you get is because you put a statement inside a lambda function, where only expressions are allowed. You could write this as a list comprehension -- something like (untested)

[lst.__setitem__(i, lst[i] + lst[i - c]) 
 for c in coins for i in range(c, maxi+1)]

but seriously -- why should you? Apart from being obscure, it also creates a pointless long list of None values.

The only thing I'd change about your code is the initialisation of lst, which is strangely spread out over three lines. The following line will be enough:

lst = [1] + [0] * (maxi + 4)
Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
2

That's because += in python is a statement, not an expression - it doesn't return any value. lambdas must contain only expressions in python.

soulcheck
  • 36,297
  • 6
  • 91
  • 90
1

Don't use a list comprehension for this- it is more Pythonic just to do

for c in coins:
    for i in range(c, maxi + 1):
        lst[i] += lst[i - c]

ETA: The reason is that list comprehensions are meant to be used for function that return values (thus ending up with a list)- it is unnecessary (and violates functional programming practices) to use them with a function that has side effects.

David Robinson
  • 77,383
  • 16
  • 167
  • 187