This is directly inspired by an excellent post by Drew Olson 5 things you can do with a Ruby array in one line. When reading it, I couldn't help but thinking of the Python versions (and how I like them more :>). So here it is:
- Summing elements
puts my_array.inject(0){|sum,item| sum + item}
sum(my_list)
- Double every item.
my_array.map{|item| item*2 }
[2 * x for x in my_list]
- Finding all items that meet your criteria.
my_array.find_all{|item| item % 3 == 0 }
[x for x in my_list if x % 3 == 0]
- Combine techniques.
my_array.find_all{|item| item % 3 == 0 }.inject(0){|sum,item| sum + item }
sum(x for x in my_list if x % 3 == 0)
- Sorting.
my_array.sort my_array.sort_by{|item| item*-1}
sorted(my_list) sorted(my_list, reverse=True)
13 comments:
If 'sum' didn't exist as a special case, then maybe it's slightly more instructive to see how you would construct it, using:
from operator import add
reduce(add, mylist)
Although I guess this isn't one line any more
Is there a nice way to markup code in the comments?
I don't think so.
Migrating away from blogger is on my somday/maybe list, so in when it happens in distant future, I'll make sure to enable some comment markup :)
Without importing a function, and on one line, Tartley's code would look something like:
reduce(lambda x, y: x + y, mylist)
Nice post! I like the Python versions better as well. :-)
Now I see why I picked Python instead of Ruby!
The 4th example (combination of techniques) is not an actual list but a generator. As each element is produced, it is accumulated by applying the addition. That's why is so cheap in terms of memory. Even better than a list.
Some cool things you can also do:
>>> list = [1,2,3,4,5,6,7,8,9]
>>> list = list[::2]
list is: [1, 3, 5, 7, 9]
(every-other outside)
>>> list = list[1::2]
list is: [2, 4, 6, 8]
(every-other inside)
>>> list = list[::-1]
list is: [9, 8, 7, 6, 5, 4, 3, 2, 1]
(reverse list)
>>> print list[::-2]
list is: [9, 7, 5, 3, 1]
(reverse every-other outside)
I stumbled on this when I thought: I remember seeing an example with 2 colons, I wonder what it will do?
I wonder what happens if you use that ruby code to sort a list of strings ( the python version works of course ;-)
You forgot the bonus!
my_array.find_all{|item| item =~ /\d{3}-\d{3}-\d{4}/ }
[x for x in l if re.match(r'\d{3}-\d{3}-\d{4}', x)]
Just wanted to let you know that I loved your post and I continued your trend, expanding the coverage to Perl 6. Thanks for doing this!
For those of you comparing Ruby and Python, let me fix your ruby:
Summing elements:
my_array.inject(&:+)
sum(my_list)
Double every item.
my_array.map{|x| x*2 }
[2 * x for x in my_list]
Finding all items that meet your criteria.
my_array.select{|x| x % 3 == 0 }
[x for x in my_list if x % 3 == 0]
Combine techniques.
my_array.select{|x| x % 3 == 0 }.inject(&:+)
sum(x for x in my_list if x % 3 == 0)
Sorting.
my_array.sort
my_array.sort.reverse
sorted(my_list)
sorted(my_list, reverse=True)
Matching by regexp (@Michael Pratt)
my_array.grep /\d{3}-\d{3}-\d{4}/
[x for x in l if re.match(r'\d{3}-\d{3}-\d{4}', x)]
@michael
My intention wasn't to compare the number of characters, but the way you express it. I kept the original var names, and wrote the Python version as I would write it myself (I believe single letter variable names are preferable for list comprehensions).
When it comes to the first example, this is not valid ruby, actually. You need one of the Rails' gems (ActiveSupport, isn't it?) to implement to_proc on symbol.
I know this is several months later, but using a symbol for reduce is supported in the Ruby core.
http://www.ruby-doc.org/core/classes/Enumerable.html#M001495
Post a Comment