Arrays/List, filters, Pytho, Ruby

2011-02-11 Thread LL.Snark

Hi,

I'm looking for a pythonic way to translate this short Ruby code :
t=[6,7,8,6,7,9,8,4,3,6,7]
i=t.index {|x| x=t[0] : i+=1

... not pythonic I think...

Or :
t=[6,7,8,6,7,9,8,4,3,6,7]
i=[j for j in range(len(t)) if t[j]http://mail.python.org/mailman/listinfo/python-list


Re: Arrays/List, filters, Pytho, Ruby

2011-02-11 Thread LL.Snark

On 11/02/2011 22:24, LL.Snark wrote:

Hi,

I'm looking for a pythonic way to translate this short Ruby code :
t=[6,7,8,6,7,9,8,4,3,6,7]
i=t.index {|x| x=t[0] : i+=1

... not pythonic I think...

Or :
t=[6,7,8,6,7,9,8,4,3,6,7]
i=[j for j in range(len(t)) if t[j]


Thx for your answers.

May I add some comments ?

=
t = [6,7,8,6,7,9,8,4,3,6,7]
i = -1
for index, item in enumerate(t):
if item < t[0]:
i = index
break

is OK for me, while a bit too long :)
==
from itertools import dropwhile
t=[6,7,8,6,7,9,8,4,3,6,7]
i = dropwhile(lambda k: t[k]>=t[0], t).__next__()
(I added the __ around next. Am i true ?)

This does not work for me.

i is effectively 7, but 7 is the second item of the array.
If you try :
t=[6,8,8,6,7,9,8,4,3,6,7]
i = dropwhile(lambda k: t[k]>=t[0], t).__next__()
You will get 8.

I guess this is because k is a value of the array, not an index.
In the first example, we compare t[6], then t[7], then t[8], t[6], t[7] 
etc... to t[0].
(It happens that the first item of the list is dropped... then the first 
element of the resulting list is 7... the answer... but it was just luck)


=
The javalicious one :

class ComparisonPredicate:
def __init__(self, func):
self.func = func
def __eq__(self, other):
return self.func(other)

t = [6, 7, 8, 6, 7, 9, 8, 4, 3, 6, 7]
print(t.index(ComparisonPredicate(lambda x: x < t[0])))

It took me some time to understand :)
It's a shame there is no built-in object like ComparisonPredicate, 
because the line t.index(ComparisonPredicate(lambda x: x < t[0])) looks 
good to me.


===
Finally, the other enumerate solution may be written like this :
t = [6,7,8,6,7,9,8,4,3,6,7]
for i, j in enumerate(t):
if j < t[0]: break
else : i=-1
Quite short.

=
Finally, with your solutions, I build another one. Here it is :
t=[6,7,8,6,7,9,8,4,3,6,7]
i,j=filter(lambda x: x[1]=t[0],enumerate(t)).__next__()

Or else :
t=[6,7,8,6,7,9,8,4,3,6,7]
t.index(filter(lambda x: xThe last one behaves like the Ruby one, if a value is found. If no walue 
is found, the Python code raises a StopException. With the Ruby code, i 
is nil.


Is there another way to access the first item of an iterator ?
( __next__() is ugly )

==
Paul, the Ruby version stops when it finds the first matching element
t=[6,7,8,6,7,9,8,4,3,6,7]
i=t.index {|x| x(I figured this out by making a 1 000 000 elements array. It was faster 
with a matching value at the beginning of the array)


Many thanks for your answers





--
http://mail.python.org/mailman/listinfo/python-list


Re: Arrays/List, filters, Pytho, Ruby

2011-02-14 Thread LL.Snark

On 12/02/2011 04:49, Terry Reedy wrote:

On 2/11/2011 4:24 PM, LL.Snark wrote:

Hi,

I'm looking for a pythonic way to translate this short Ruby code :
t=[6,7,8,6,7,9,8,4,3,6,7]
i=t.index {|x| x



What does Ruby do if there is no such element?
For Python, the answer should be either None or ValueError.


Ruby code :
# What is the index, in array t,
# of the first element x such that x 8
# Raises an exception if no value found
==
The following solutions raise a StopIteration exception if no value is 
found. See below how to use the second argument of next


next(filter(lambda x: x[1] (8,4)

from itertools import dropwhile
next(dropwhile(lambda x: x[1]>=t[0],enumerate(t)))
=> (8,4)

Or if you don't like enumerate :
next(filter(lambda x: x 4
t.index(next(filter(lambda x: x 8

next(filter(t[0].__gt__, t))
=> 4

Generators and enumerate :

next(i for i,v in enumerate(t) if v 8

If no values exists, this raises an exception. Second argument of next
can help you :

next((i for i,v in enumerate(t) if v 8  # returns None if no value found
===

If you use lists instead of generators, it works, but you have to go 
across the whole array :


[x 8

[i for i,v in enumerate(t) if v < t[0]]
=> [ 8, 9 ] (indices of all array values less than t[0]

If you are only interested in the first value :
[i for i,v in enumerate(t) if v < t[0]][0]
=> 8 (but raises an exception if the list if no value is found)
[i for i,v in enumerate(t) if v < t[0]][0:1]
=> [8] (return an empty list if no value is found)

Keep in mind that, even if you just select the first value [0] or [0:1], 
you go across the whole array t


=
I found it very interesting to read all these short lines of code.
Thanks to : Chris, Ian, Paul, Jon, Therry, Bruno, Arnaud and people that 
have no name (like me...)



next(((i,v) for i,v in enumerate(t) if vhttp://mail.python.org/mailman/listinfo/python-list