Velocity Reviews > Arrays/List, filters, Pytho, Ruby

# Arrays/List, filters, Pytho, Ruby

DouhetSukd
Guest
Posts: n/a

 02-12-2011
On Feb 11, 1:24*pm, "LL.Snark" <(E-Mail Removed)> 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.first}
>
> If you don't know Ruby, the second line means :
> What is the index, in array t, of the first element x such that x<t[0].
>
> If can write it in python several ways :
> t=[6,7,8,6,7,9,8,4,3,6,7]
> i=0
> while t[i]>=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]<t[0]][0]
>
> ...too cryptic...
>
> I'm using Python 3.
>
> Thx

[i for i,v in enumerate(t) if v < t[0]][0:1]

empty list if no match.

Arnaud Delobelle
Guest
Posts: n/a

 02-12-2011
"LL.Snark" <(E-Mail Removed)> writes:

> 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.first}
>

In Python3:

>>> t = [6,7,8,6,7,9,8,4,3,6,7]
>>> next(filter(t[0].__gt__, t))

4

--
Arnaud

Arnaud Delobelle
Guest
Posts: n/a

 02-12-2011
Arnaud Delobelle <(E-Mail Removed)> writes:

> "LL.Snark" <(E-Mail Removed)> writes:
>
>> 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.first}
>>

>
> In Python3:
>
>>>> t = [6,7,8,6,7,9,8,4,3,6,7]
>>>> next(filter(t[0].__gt__, t))

> 4

Oops! I realised my mistake the moment I sent the reply. You can do this
to get the index:

>>> next(i for i, x in enumerate(t) if x < t[0])

7

--
Arnaud

LL.Snark
Guest
Posts: n/a

 02-14-2011
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<t.first}
>>
>> If you don't know Ruby, the second line means :

>
> 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<t[0].
t=[6,7,8,6,7,9,8,9,4,3,6,7]
i=t.index {|x| x<t.first}

Stops when the first value is found.
If no value is found, then i is nil (None equivalent)

(The answer if index 8, value 4)

Here is the last summary (Python 3) :
================================================== ===
t=[6,7,8,6,7,9,8,9,4,3,6,7]

and then... :
================================================== =====
for i, j in enumerate(t):
if j < t[0]: break
else : i=-1

# Now i==8 and j==4
# i==-1 if no value is found
================================================== ====
class ComparisonPredicate:
def __init__(self, func):
self.func = func
def __eq__(self, other):
return self.func(other)
t.index(ComparisonPredicate(lambda x: x < t[0]))
=> 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]<t[0],enumerate(t)))
=> (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<t[0],t))
=> 4
t.index(next(filter(lambda x: x<t[0],t))
=> 8

next(filter(t[0].__gt__, t))
=> 4
================================================== ==============
Generators and enumerate :

next(i for i,v in enumerate(t) if v<t[0])
=> 8

If no values exists, this raises an exception. Second argument of next

next((i for i,v in enumerate(t) if v<t[0]),None)
=> 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<t[0] for x in t].index(True)
=> 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 v<t[0]),None)