Re: [Tutor] reduce with comprehension

2005-11-24 Thread Alan Gauld
Hi John,

 Everything is possible with list comprehensions!

 [x for z in a for y in z for x in y]
 [1, 2, 3, 31, 32, 4, 5, 6, 7, 71, 72, 8, 9]

impressive!

But in the general case can you do the same job as 
reduce in a list comprehension? ie apply an operation 
to the first two elements of a sequence and replace 
them with the result, then repeat until the list becomes 
a single value?

I cannot think of a way to do that in the generaln case 
with a comprehension. I'd be interested to see if there is a 
recipe for that.

Alan G

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-24 Thread John Fouhy
On 22/11/05, Alan Gauld [EMAIL PROTECTED] wrote:
 But in the general case can you do the same job as
 reduce in a list comprehension? ie apply an operation
 to the first two elements of a sequence and replace
 them with the result, then repeat until the list becomes
 a single value?

Well ... probably not.  I may have been exaggerating ever-so-slightly
in my praise of list comprehensions :-)

Although you may be able to cheat:
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204297

(but I'm pretty certain that this feature is on Guido's hitlist)

Hmm...

 def f(x, y):
...  return x + y
...
 arr = range(10)
 sum(arr)  # Our target
45
 tmp = [0]
 [f(x, y) for x in arr for y in [tmp[-1]] if tmp.append(f(x, y)) or True][-1]
45

Let's try some more...

 def f(x, y):
...  return x*y
...
 arr = range(1, 10)# Don't want to include 0!
 reduce(f, arr)   # Our target
362880
 tmp = [1]
 [f(x, y) for x in arr for y in [tmp[-1]] if tmp.append(f(x, y)) or True][-1]
362880
 print 'Magic!'
Magic!

--
John.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-24 Thread Alan Gauld
 But in the general case can you do the same job as
 reduce in a list comprehension?
 def f(x, y):
...  return x + y
...
 tmp = [0]
 [f(x, y) for x in arr for y in [tmp[-1]] if tmp.append(f(x, y)) or 
 True][-1]
45

Let's try some more...

 def f(x, y):
...  return x*y
...
 tmp = [1]
 [f(x, y) for x in arr for y in [tmp[-1]] if tmp.append(f(x, y)) or 
 True][-1]
362880

OK, you've nearly convinced me that its possible but I think I still
prefer reduce()! :-)

Alan G.


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-21 Thread Brian van den Broek
János Juhász said unto the world upon 2005-11-21 01:20:
 Hi,
 
 I can't imagine how this could be made with list comprehension.
 
 
import operator
a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
reduce(operator.add, a) # it makes a long list now
 
 ([1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9])
 
 When I make list comprehension, the list hierarchy is allways the same or
 deeper than the original hierarchy. But now it should be reduced with one
 level.
 
 
 
[item for item in a] # the deepnes is the same
 
 [([1], [2], [3, 31, 32], [4]), ([5], [6], [7, 71, 72]), ([8], [9])]
 
[(item, item) for item in a] # it is deeper with one level

 
 
 
 Is it possible to substitute reduce with comprehension anyway ?
 
 
 Yours sincerely,
 __
 János Juhász
 

Hi János,

I think it is.

  a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
  b = []
  [b.extend(x) for x in a]
[None, None, None]
  b
[[1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9]]


But don't do that :-)  Seems very poor form to me, as the desired 
operation is a side effect of the creation of the list via the 
comprehension.

If, however, you are just trying to avoid reduce:

  b=[]
  for x in a:
b.extend(x)


  b
[[1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9]]
 

Notice, too, that these ways result in a list of lists, whereas yours 
provided a tuple of lists.

HTH,

Brian vdB

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-21 Thread Alan Gauld
 a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
 reduce(operator.add, a) # it makes a long list now
([1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9])

When I make list comprehension, the list hierarchy is allways the same or

 [item for item in a] # the deepnes is the same
[([1], [2], [3, 31, 32], [4]), ([5], [6], [7, 71, 72]), ([8], [9])]
 [(item, item) for item in a] # it is deeper with one level

You are not using operator add anywhere in there. 
So you won't reduce anything!

But reduce is tricky to reproduce using comprehensions because 
it involves combining two elements using an operation. And one 
of the elements is the running result.

So

count = 0
[count + item for item in alist]

won't work because we never change count - and assignments 
aren't allowed inside a comprehension.

There may be a clever way of doing it but I can't think of it and 
certainly not a way that would be as readable as reduce()!

Do you have any particular need to avoid reduce? Or is it just curiosity?

Alan g


___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-21 Thread Kent Johnson
János Juhász wrote:
 Hi,
 
 I can't imagine how this could be made with list comprehension.
 
import operator
a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
reduce(operator.add, a) # it makes a long list now
 
 Is it possible to substitute reduce with comprehension anyway ?

Not that I know. Why are you trying to eliminate reduce()? If it is for 
compatibility with Python 3.0, PEP 3000 recommends replacing reduce() with an 
explicit loop.
http://www.python.org/peps/pep-3000.html#built-in-namespace

Kent
-- 
http://www.kentsjohnson.com

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-21 Thread John Fouhy
On 21/11/05, János Juhász [EMAIL PROTECTED] wrote:
 I can't imagine how this could be made with list comprehension.

  import operator
  a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
  reduce(operator.add, a) # it makes a long list now
 ([1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9])

Everything is possible with list comprehensions!

 a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
 [x for y in a for x in y]
[[1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9]]

We can even go a level deeper!

 [x for z in a for y in z for x in y]
[1, 2, 3, 31, 32, 4, 5, 6, 7, 71, 72, 8, 9]

Just make sure your depth is consistent throughout.

And remember that that single-line expression is hiding nested FOR loops!

--
John.
___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] reduce with comprehension

2005-11-21 Thread János Juhász
Hi John,

thanks it.

It is great. I looked for it, but I couldn't made it.
I have tried it with wrong order:
# I have tried it so
[x for x in y for y in a]
[[8], [8], [8], [9], [9], [9]] # that is wrong,

# Instead of that you wrote
[x for y in a for x in y]
[[1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9]]


Yours sincerely,
__
János Juhász


[EMAIL PROTECTED] wrote on 2005.11.21 23:26:03:

 On 21/11/05, János Juhász [EMAIL PROTECTED] wrote:
  I can't imagine how this could be made with list comprehension.
 
   import operator
   a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
   reduce(operator.add, a) # it makes a long list now
  ([1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9])

 Everything is possible with list comprehensions!

  a = (([1],[2],[3,31,32],[4]), ([5],[6],[7, 71, 72]), ([8],[9]))
  [x for y in a for x in y]
 [[1], [2], [3, 31, 32], [4], [5], [6], [7, 71, 72], [8], [9]]

 We can even go a level deeper!

  [x for z in a for y in z for x in y]
 [1, 2, 3, 31, 32, 4, 5, 6, 7, 71, 72, 8, 9]

 Just make sure your depth is consistent throughout.

 And remember that that single-line expression is hiding nested FOR loops!

 --
 John.

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor