# Convert this python code into elixir

**URL:** <https://forum.elixirforum.com/t/convert-this-python-code-into-elixir/21834>\
**Category:** Questions\
**Tags:** list-comprehension\
**Created:** [April 23, 2019, 12:09am UTC](https://forum.elixirforum.com/t/convert-this-python-code-into-elixir/21834 "2019-04-23T00:09:43Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![isaac-rstor](https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/isaac-rstor/32/13395_2.png) [@isaac-rstor](https://forum.elixirforum.com/u/isaac-rstor)\
**Post date:** [April 23, 2019, 5:47pm UTC](https://forum.elixirforum.com/t/convert-this-python-code-into-elixir/21834/4 "2019-04-23T17:47:22Z")

</div>

here’s a slightly more idiomatic version, although I think there might be some corner cases where it’s not as even as it could be:

```elixir
defmodule M do 

  @doc """
  interleaves a short list b, into a long list a, such that the
  presence of the short list is evenly spaced in the long list.

  iex> M.interleave([1,2,3,4,5,6,7],[:a, :b])
  [1, 2, :a, 3, 4, 5, :b, 6, 7]
  """
  def interleave(a, b) do
    a_ct = Enum.count(a)
    b_ct = Enum.count(b)

    # calculates how many items are in the cycle of drawing from a vs b.
    recurrence = div(a_ct, b_ct) + 1

    # calculate how much we have to offset the recurrence by to center it.
    offset = div(a_ct + b_ct - ((b_ct - 1) * recurrence), 2)

    # bootstrap the initial condition
    interleave(a, b, offset, recurrence, [])
  end

  # terminating condition: we've exhausted all the items; since we put values on the front
  # in the tail calls, reverse the list.
  def interleave([], [], _, _, rev_list), do: Enum.reverse(rev_list)
  def interleave(a, [b_hd | b_tl], n, recurrence, list_so_far) 
    when rem(n, recurrence) == 0 do
    # draw from the shorter list every <recurrence>. Put on front
    # of the list we're building, then tail call in.
    interleave(a, b_tl, n + 1, recurrence, [b_hd | list_so_far])
  end
  def interleave([a_hd | a_tl], b, n, recurrence, list_so_far) do
    # draw from the longer list. Put on front of the list we're building, 
    # then tail call in.
    interleave(a_tl, b, n + 1, recurrence, [a_hd | list_so_far])
  end  

end

```

if the enum.reverse thing is a bit confusing, you can also do this:

```elixir
def interleave([], [], _, _, list), do: list
def interleave(a, [b_hd | b_tl], n, interval, list_so_far) 
  when rem(n, interval) == 0 do
  interleave(a, b_tl, n + 1, interval, list_so_far ++ [b_hd])
end
def interleave([a_hd | a_tl], b, n, interval, list_so_far) do
  interleave(a_tl, b, n + 1, interval, list_so_far ++ [a_hd])
end  

```

---

_[View the full topic](https://forum.elixirforum.com/t/convert-this-python-code-into-elixir/21834)._
