Python Equivalent of Ruby's Each_Slice(Count)

Python equivalent of Ruby's each_slice(count)

There is a recipe for this in the itertools documentation called grouper:

from itertools import izip_longest
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)

Use like this:

>>> l = [1,2,3,4,5,6]
>>> for a,b in grouper(2, l):
>>> print a, b

1 2
3 4
5 6

Is there a Pandas equivalent to each_slice to operate on dataframes

There isn't a built in method as such but you can use numpy's array_slice, you can pass the dataframe to this and the number of slices.

In order to get ~100 size slices you'll have to calculate this which is simply the number of rows/100:

import numpy as np
# df.shape returns the dimensions in a tuple, the first dimension is the number of rows
np.array_slice(df, df.shape[0]/100)

This returns a list of dataframes sliced as evenly as possible

Ruby: each_slice, map, inject

You can easily try this by typing each step into an interactive Ruby prompt (irb).

Let's say input is:

["1", "0", "0", "1", 
"0", "1", "0", "1",
"1", "0", "1", "0",
"0", "1", "1", "0"]

The each_slice(4) breaks it up into:

[["1", "0", "0", "1"], 
["0", "1", "0", "1"],
["1", "0", "1", "0"],
["0", "1", "1", "0"]]

In this case, the map is unnecessary and does nothing.

The inject is the same as reduce. You give it an initial value, and the block gets called with that and the first item of the list, and then the result of that call and the next item in the list, etc. etc.

So it gets called with:

[[], ["1", "0", "0", "1"]]
[[9], ["0", "1", "0", "1"]]
[[9, 5], ["1", "0", "1", "0"]]
[[9, 5, 10], ["0", "1", "1", "0"]]

and finally returns [9, 5, 10, 6].

In Python, the closest equivalent would be very un-Pythonic:

reduce(
(lambda sum, s: (sum.append(int(''.join(s), 2)) or sum))
(input[i * 4:(i + 1) * 4] for i in range(4)),
[])

So instead you could do something like:

slices = (input[i * 4:(i + 1) * 4] for i in range(4))
sum = [int(''.join(s), 2) for s in slices]

Which in Ruby would also be better:

input.each_slice(4).map { |s| s.join.to_i(2) }

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]]

Equivalent of Ruby's Enumerable#each_slice method in FSharp

You're looking for List.chunkBySize, which was added in F# 4.0. There are also Seq and Array variants.

making group and list in python

Just use a simple one-line list-comprehension:

[[l[i]+l[i+1] for i in range(0,len(l)-1,2)] for l in last_1]

which gives:

[['33', '2F', '2C', '2D', '2A', '28', '7C', '3B', '2E', '2E', '33', '34', '33', '30', '3B', '28', '33', '2D', '2E'], ['2C', '2A', '33', '2E', '28', '74', '7A', '53', '7C', '39', '2D', '2F', '2F', '3B', '2E', '38', '7C', '23', '2D', '27', '7C', '28', '2D', '7C', '28', '37', '2A', '2F', '33', '2E', '3B', '28', '37', '7C', '23', '2D', '27', '2A', '7C', '34', '27', '2F', '3B', '2E', '7A', '73'], ['38', '37', '36', '7C', '31', '33', '30', '30', '74', '3B', '2A', '35', '73', '62'], ['7C', '7C', '7C', '7C', '2A', '37', '28', '27', '2A', '2E', '7C', '3B', '2A', '35', '7C', '71', '7C', '7A', '7C', '51', '33', '30', '30', '7C', '37', '24', '37', '39', '27', '28', '37', '38', '7A'], ['31', '33', '30', '30', '74', '7A', '34', '37', '30', '30', '2D', '7A', '73']]

If you need this explaining drop a comment and I will be happy to explain each part in detail in this answer, but I will assume you can work it out yourself...

Get the count of values in an array that fall within ranges of a hash in Ruby

result = ranges.keys.each_with_object({}) do |range, memo|
count = sorted_prices.count do |price_obj|
range.cover?(price_obj["price"])
end
memo[range] = count
end

Python list comprehension = Ruby select / reject on index rather than element

The method order is relevant:

arr.each_with_index.select { |e, i| i % 3 == 0 }
#=> [[10, 0], [40, 3], [70, 6], [100, 9]]

versus:

arr.select.each_with_index { |e, i| i % 3 == 0 }
#=> [10, 40, 70, 100]

Since select returns an enumerator, you could also use Enumerator#with_index:

arr.select.with_index { |e, i| i % 3 == 0 }
#=> [10, 40, 70, 100]

Regarding your slice equivalent, you can use map (or its alias collect) to collect the items in an array:

(0..arr.length).step(3).map { |e| arr[e] }
#=> [10, 40, 70, 100]

or values_at to fetch the items at the given indices:

arr.values_at(*(0..arr.length).step(3))
#=> [10, 40, 70, 100]

* turns the argument into an array (via to_a) and then into an argument list, i.e.:

arr.values_at(*(0..arr.length).step(3))
arr.values_at(*(0..arr.length).step(3).to_a)
arr.values_at(*[0, 3, 6, 9])
arr.values_at(0, 3, 6, 9)

Slightly shorter:

arr.values_at(*0.step(arr.size, 3))
#=> [10, 40, 70, 100]

How slice an array while avoiding duplicate values in each slice?

a = [1,2,3,3,3,3,3,3,3,3,3,4,5,6,6,7,8,9,10,11]

You can test if slices are "unique" by:

a.each_slice(2).all?{|x| x == x.uniq}

So now you just shuffle until you get what you want:

a.shuffle! until a.each_slice(2).all?{|x| x == x.uniq}

The easiest way to avoid an infinite loop is with timeout:

require 'timeout'
# raise an error if it takes more than 1 second
timeout(1){ a.shuffle! until a.each_slice(3).all?{|x| x == x.uniq} }

Ruby array each_slice_with_index?

Like most iterator methods, each_slice returns an enumerable when called without a block since ruby 1.8.7+, which you can then call further enumerable methods on. So you can do:

arr.each_slice(2).with_index { |(a, b), i| puts "#{i} - #{a}, #{b}" }


Related Topics



Leave a reply



Submit