-2

I’m trying to create a run length for this matrix (see below) in Python that prints the matrix to a list in the following format [84, 2, 90, 2, 88, 1...].

The matrix layout

84 84 90 90
88 93 93 93
93 93 93 93
87 87 87 94

I don't have a lot of experience with run length loops so any helpful suggestions would be appreciated.

m0nhawk
  • 22,980
  • 9
  • 45
  • 73
Veridian
  • 9
  • 1
  • 4
  • Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation, as suggested when you created this account. [On topic](http://stackoverflow.com/help/on-topic), [how to ask](http://stackoverflow.com/help/how-to-ask), and [... the perfect question](https://codeblog.jonskeet.uk/2010/08/29/writing-the-perfect-question/) apply here. StackOverflow is not a design, coding, research, or tutorial resource. However, if you follow whatever resources you find on line, make an honest coding attempt, and run into a problem, you'd have a good example to post. – Prune Nov 15 '18 at 21:22
  • What's supposed to be the run length of 93? 3 or 7? – blhsing Nov 15 '18 at 21:56

3 Answers3

1

One way might be to use the list count() method on each sublist in the matrix:

>>> m = [[84, 84, 90, 90],
...      [88, 93, 93, 93],
...      [93, 93, 93, 93],
...      [87, 87, 87, 94]]

>>> l = []
>>> for row in m:
...     for x in sorted(set(row)):
...         l.extend([x, row.count(x)])

Or if you prefer one-liners:

[l.extend([x, row.count(x)]) for row in m for x in sorted(set(row))]

Then,

>>> print(l)
[84, 2, 90, 2, 88, 1, 93, 3, 93, 4, 87, 3, 94, 1]
0

The answer given by @davedwards is extremely elegant.

Here is the solution that I wrote, which has the same run-time as his solution on my machine.

def run_length_encoding(matrix):
    # List for storing run length encoding
    encoding = []

    # Counts the number of occurrences
    count = 0

    # Initialize previous element to first element in matrix
    previous_element = matrix[0][0]

    for row in matrix:
        for current_element in row:
            if current_element == previous_element:
                count += 1
            else:
                encoding.append(previous_element)
                encoding.append(count)

                # Reset counter and update previous element
                count = 1
                previous_element = current_element

    # Append last element since loop exited.
    encoding.append(previous_element)
    encoding.append(count)

    return encoding
0

Using the high-performance pyrle library for run length arithmetic:

# pip install pyrle
# or
# conda install -c bioconda pyrle

from pyrle import Rle
data = [int(n) for n in "84 84 90 90 88 93 93 93 93 93 93 93 87 87 87 94".split()] 
rle = Rle(data)
rle
# +--------+------+------+------+------+------+------+
# | Runs   | 2    | 2    | 1    | 7    | 3    | 1    |
# |--------+------+------+------+------+------+------|
# | Values | 84.0 | 90.0 | 88.0 | 93.0 | 87.0 | 94.0 |
# +--------+------+------+------+------+------+------+
# Rle of length 16 containing 6 elements

rle + rle
# +--------+-------+-------+-------+-------+-------+-------+
# | Runs   | 2     | 2     | 1     | 7     | 3     | 1     |
# |--------+-------+-------+-------+-------+-------+-------|
# | Values | 168.0 | 180.0 | 176.0 | 186.0 | 174.0 | 188.0 |
# +--------+-------+-------+-------+-------+-------+-------+
# Rle of length 16 containing 6 elements
The Unfun Cat
  • 29,987
  • 31
  • 114
  • 156