1

So I've got a string of bytes which represents cubes in three dimensions. The coordinates are ordered like this:

[x0y0z0, x0y1z0, x0y2z0, ..., x0y127z0, x0y0z1, x0y1z1, ..., x15y127z15]

I'd like to split this into 128 lists, one for each Y coordinate. This code already does that, but I think inefficiently. Is there some way to split this list based on mod(128) of the index?

From the original code:

col.extend(izip_longest(*[iter(file["Level"]["Blocks"].value)]*128))

That takes quite a while, and I think it should be possible to make something better performing by avoiding the *128 part of this. But zipping is definitely not my strong side, and neither is binary file handling.

3
  • 1
    Your example isn't clear. Is it a list of strings or a string? Why are you showing a y127? is this the 127'th y coordinate? I thought there were only 16. Commented Oct 29, 2010 at 10:55
  • 2
    This is ambiguous. Please provide code showing actual input data (not pseudocode that requires interpretation), and the expected result from that data. Commented Oct 29, 2010 at 10:57
  • The *128 part does not take long, you are just making 128 references to the same iterator Commented Oct 29, 2010 at 12:33

4 Answers 4

3
# l = [x0y0z0, ...]
def bucketsofun(l, sp=16):
  r = [[] for x in range(sp)]
  for b, e in itertools.izip(itertools.cycle(r), l):
    b.append(e)
  return r
Sign up to request clarification or add additional context in comments.

2 Comments

Do you have more descriptive names for b and e?
bucket and element, if you prefer.
2

Something like this might be worth trying

L = file["Level"]["Blocks"].value
col += [L[i::128] for i in range(127)]

Comments

0

Itertools can do it too:

from itertools import izip, izip_longest, chain

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

# you have something like this
# [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4]
l = list(chain.from_iterable(range(5) for _ in range(5)))

# you want to put all the 0s, 1s (every 5th element) together
print list(izip(*grouper(5, l)))
# [(0, 0, 0, 0, 0), (1, 1, 1, 1, 1), ... , (4, 4, 4, 4, 4)]

Comments

0

Faster way to do this is using reshape() function from NumPy

original_1D_array = [1, 2, 3, 4, 5, 6]
modulo = 3

new_2D_array = np.reshape(original_1D_array, (-1, modulo))

# new_2D_array = [[1, 2, 3], [4, 5, 6]]

Now we just need to transpose this matrix

new_2D_array = new_2D_array.T

# new_2D_array = [[1, 4], [2, 5], [3, 6]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.