0

I'm looking for a way to get 3 values from a list at a time. Let's say I have a list of dimensions for x items: packages = [length, width, height, length, width, height,...] and I want to get the l, w , and h for each item separately. Anyone know of a way to do this? I do know the value of x if that makes any difference.

The following was in the code I used but it doesn't seem to work:

packages = [2400, 1000, 800, 2400, 1000, 1000, 2400, 1000, 1000]
for each in packages:
        l, w, h = each[3:]
shongololo
  • 21
  • 5
  • 1
    See: https://stackoverflow.com/questions/312443/how-do-i-split-a-list-into-equally-sized-chunks – slothrop Jun 27 '23 at 12:29
  • I've asked a similair question: https://stackoverflow.com/questions/54374598/how-would-i-unpack-a-flat-list – Jab Jun 27 '23 at 12:34

3 Answers3

2

You can slice the list at gaps of 3.

packages = [2400, 1000, 800, 2400, 1000, 1000, 2400, 1000, 1000]
packages = [packages[x:x+3] for x in range(0, len(packages), 3)]
print(packages)

Output is

[[2400, 1000, 800], [2400, 1000, 1000], [2400, 1000, 1000]]
Zero
  • 1,807
  • 1
  • 6
  • 17
1

You can use the "zip iterator with itself" trick:

i = iter(packages)
for l, w, h in zip(i, i, i):
    # do unspeakable things

Or for generic chunk sizes ``n:

for chunk in zip(*(i for _ in range(n))):
user2390182
  • 72,016
  • 6
  • 67
  • 89
1

If you know the list will be of length % n == 0 thenyou can use the itertools recipe called batched

def batched(iterable, n):
    "Batch data into tuples of length n. The last batch may be shorter."
    # batched('ABCDEFG', 3) --> ABC DEF G
    if n < 1:
        raise ValueError('n must be at least one')
    it = iter(iterable)
    while batch := tuple(islice(it, n)):
        yield batch

In use:

packages = [2400, 1000, 800, 2400, 1000, 1000, 2400, 1000, 1000]
for l, w, h in batched(packages, 3):
    ...

And if you want more options as far as iterables that do not have length % n == 0 length then you can use the grouper recipe:

def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
    "Collect data into non-overlapping fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx
    # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError
    # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF
    args = [iter(iterable)] * n
    if incomplete == 'fill':
        return zip_longest(*args, fillvalue=fillvalue)
    if incomplete == 'strict':
        return zip(*args, strict=True)
    if incomplete == 'ignore':
        return zip(*args)
    else:
        raise ValueError('Expected fill, strict, or ignore')

Finally, without using itertools, (but it's a bit hacky) from this answer:

d = iter(i)
for l, w, h in zip(*[d]*3):
    ...
Jab
  • 26,853
  • 21
  • 75
  • 114