Ruby Methods Equivalent of "If a in List" in Python

Ruby methods equivalent of if a in list in python?

Use the include?() method:

(1..10).include?(5) #=>true
(1..10).include?(16) #=>false

EDIT:
(1..10) is Range in Ruby , in the case you want an Array(list) :

(1..10).to_a #=> [1,2,3,4,5,6,7,8,9,10]

From Ruby to Python - Is there an equivalent of try?

Dictionaries: dict.get

You can use dict.get:

d = {'foo' : 'bar'}

print(d.get('foo'))
'bar'

print(d.get('xxxxx'))
None

You can also pass a default parameter to get:

print(d.get('xxxxx', 'Invalid Key!'))
Invalid Key!

The default value is printed out when the key does not exist in the dictionary.



Lists: custom try-except block

Unfortunately, lists do not have a dict.get equivalent in their API, so you'll need to implement one yourself. Thankfully, you can extend the list class and override __getitem__ to do this cleanly.

class MyList(list):
def __getitem__(self, idx, default='oops'):
try:
return super().__getitem__(idx)
except IndexError:
return default

l = MyList([10, 20])

l[1]
# 20

l[3]
# 'oops'


Searching through a list of objects in Ruby and returning result(s) or raising an error if not found

If you are doing complex things with each, then reading this documentation is the
first step.

Documentation for Enumerable

find is the obvious method that comes to mind, but there are others such as collect or map that might meet your needs as well. Two nested each loops is very un-Ruby like. The inner loop might look like this

matches = @obj_list.find { |obj| func_returning_hash(obj.some_method)[@key] == search }

raise "ERROR: No obj found matching search #{search}" if matches.nil?
results << matches.map { |obj| func_creating_result(obj) }

That's still fairly ugly and not very Ruby-like.

There are lots of ruby style checkers out there these days. Sandi-meter, reek, etc. Using these tools will help you a lot with grokking the ruby way. Coming from python they will seem quite picky and silly, but if you want to get the Ruby way they are very useful.

As an aside, this code screams for a refactoring. You are breaking almost all the basic rules for designing reusable objects. But that can wait...

Sandi Metz Rules for Object Design

Python equivalent for Ruby combination method

The itertools module has a combinations method which does this for you.

itertools.combinations(a, len)

Demo:

>>> a = [1, 2, 3, 4]
>>> import itertools
>>> itertools.combinations(a, 2)
<itertools.combinations object at 0x109c276d8>
>>> list(itertools.combinations(a, 2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
>>> list(itertools.combinations(a, 3))
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]
>>> list(itertools.combinations(a, 4))
[(1, 2, 3, 4)]

Python equivalent to Ruby Array.each method

Does Python have a nice and short closure/lambda syntax for it?

Yes, but you don't want it in this case.

The closest equivalent to that Ruby code is:

new_values = map(print, [1, 2, 3])

That looks pretty nice when you already have a function lying around, like print. When you just have some arbitrary expression and you want to use it in map, you need to create a function out of it with a def or a lambda, like this:

new_values = map(lambda x: print(x), [1, 2, 3])

That's the ugliness you apparently want to avoid. And Python has a nice way to avoid it: comprehensions:

new_values = [print(x) for x in values]

However, in this case, you're just trying to execute some statement for each value, not accumulate the new values for each value. So, while this will work (you'll get back a list of None values), it's definitely not idiomatic.

In this case, the right thing to do is to write it explicitly—no closures, no functions, no comprehensions, just a loop:

for x in values:
print x

Is there a Python equivalent of Ruby's 'any?' function?

any(pred(x) for x in lst)

alternatively

from itertools import imap
any(imap(pred, lst))

Python Equivalent to Ruby's #each_cons?

For such things, itertools is the module you should be looking at:

from itertools import tee, izip

def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)

Then:

>>> list(pairwise([1, 2, 3, 4]))
[(1, 2), (2, 3), (3, 4)]

For an even more general solution, consider this:

def split_subsequences(iterable, length=2, overlap=0):
it = iter(iterable)
results = list(itertools.islice(it, length))
while len(results) == length:
yield results
results = results[length - overlap:]
results.extend(itertools.islice(it, length - overlap))
if results:
yield results

This allows arbitrary lengths of subsequences and arbitrary overlapping. Usage:

>> list(split_subsequences([1, 2, 3, 4], length=2))
[[1, 2], [3, 4]]
>> list(split_subsequences([1, 2, 3, 4], length=2, overlap=1))
[[1, 2], [2, 3], [3, 4], [4]]

Ruby equivalent of Python's `repr()`?

Based on the helpful comments from jeremy04 and Jörg W Mittag, I realize that there is nothing in Ruby which corresponds to repr, and that I can't make use of a simple repr-like method in all class instances without monkey-patching class Object itself. However, I realize that if I just make repr a standalone function, I can get the same functionality without monkey-patching and by doing repr(obj) instead of obj.repr whenever I want this info for a given object. The following stand-alone function works ...

def repr(obj)
attrhash = {}
obj.instance_variables.sort.each {
|v|
attrhash[v] = instance_variable_get(v)
}
{
:string => obj.inspect,
:methods => obj.class.instance_methods.sort,
:attributes => attrhash
}
end

I have this function return a hash instead of a string so that I can do things like this:

repr(obj)[:attributes].

I can always do repr(obj).to_s if I want a string.

Also, I could make this into a class. I'll leave that as an exercise for the reader. :)

if/elsif/else return behavior difference between Ruby and Python

The Ruby code isn't very idiomatic. The last return in the if-elsif-else branch is a red herring and inconsistent with the other branches in the conditional chain. There's an implicit return on the other branches in the if-elsif-else chain as well.

To generalize the above idea, in all Ruby functions and methods, if control reaches the end of the function without encountering a return, the return value is that of the last expression evaluated. In a conditional chain, that'd be whichever branch was taken.

A minimal example is:

def foo(n)
if n == 0
"zero"
elsif n == 1
"one"
else
"something else"
end
end

puts foo(0) # => zero
puts foo(1) # => one
puts foo(2) # => something else

Adding returns to any or all of the above branches does nothing to change the behavior, and is normally omitted.

Python's implicit return, on the other hand, is always None. Returning a non-None value involves using an explicit return ("explicit is better than implicit" I guess?).

def foo(n):
if n == 0:
return "zero"
elif n == 1:
return "one"
else:
return "something else"

print(foo(0)) # => zero
print(foo(1)) # => one
print(foo(2)) # => something else

Another note about the Ruby code: usually ! after a function/method name is used for in-place algorithms, that is, ones that modify the input, or otherwise more dangerous versions of non-bang methods. Since quickselect! doesn't modify any class state, it's confusing that it has a bang.



Related Topics



Leave a reply



Submit