user5354933
user5354933

Reputation:

With a for loop, how could I make it so that two objects are being iterated?

Forgive me if the verbiage isn't correct. So I'm working with some JSON data and I want to try and print some columnized output so that two or three of the objects will be printed over each pass. Right now, this would just iterate over one as expected.

data = json.loads(subprocess.check_output(["some_command_here"]))

for obj in data:
    print obj['key_a']

Output

value_a
value_b
value_c
value_d
value_e

What I'm trying to achieve is something like:

value_a     value_b     value_c
value_d     value_e

Where each group of objects is printed on one row. So first iteration handles value_a, value_b, and value_c, the next one handles value_d, value_e, and value_f is applicable, etc.

How does iteration change in this case? The other thing if it warrants consideration is the number of objects in data is dynamic. Could be 1, could be 5, could be 20+.

Upvotes: 0

Views: 55

Answers (2)

zwer
zwer

Reputation: 25829

There are many ways to skin this cat, here's a procedural one as a generator:

def iterate_columns(iterable, columns=4):
    result = []
    for item in iterable:
        result.append(item)
        if len(result) >= columns:
            yield result
            result = []
    if result:
        yield result

your_list = ["value_a", "value_b", "value_c", "value_d", "value_e"]
for row in iterate_columns(your_list, 3):
    print(row)  # feel free to print your data however you want

# prints:
# ['value_a', 'value_b', 'value_c']
# ['value_d', 'value_e']

Or a slicing one, again as a generator function:

def iterate_columns(iterable, columns=4):
    for i in xrange(0, len(iterable), columns):  # replace with range() on Python 3.x
        yield iterable[i:i+columns]

And finally, probably the fastest for use in-place - the same concept using list comprehension:

[your_list[i:i+3] for i in xrange(0, len(your_list), 3)]  # replace 3 with number of columns

Upvotes: 0

wim
wim

Reputation: 363476

This is the itertools grouper recipe:

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

Your use case would look something like:

from __future__ import print_function

for objs in grouper(data, 3, fillvalue=''):
    print(*objs, sep='     ')

Upvotes: 1

Related Questions