fox
fox

Reputation: 16536

python: iterate through two objects in a list at once

Have a call to an SQL db via python that returns output in paired dictionaries within a list:

[{'Something1A':Num1A}, {'Something1B':Num1B}, {'Something2A':Num2A} ...]

I want to iterate through this list but pull two dictionaries at the same time.

I know that for obj1, obj2 in <list> isn't the right way to do this, but what is?

Upvotes: 1

Views: 10382

Answers (7)

eyquem
eyquem

Reputation: 27585

simply

in Python 2

li = [{'Something1A':10}, {'Something1B':201}, {'Something2A':405} ]
from itertools import imap
for a,b in imap(lambda x: x.items()[0], li):
    print a,b

in Python 3, map() is already a generator

Upvotes: 0

RussW
RussW

Reputation: 437

I believe the Python idiom for grouping items in an iterable is

zip(*[iter(iterable)])*n)

Where iterable is your list of dictionaries and n is 2 if you want them in groups of 2.

The solution would then look like this.

>>> data = [{'A':1}, {'B':2}, {'C':3}, {'D':4}]
>>> for dict1, dict2, in zip(*[iter(data)]*2):
    print dict1, dict2


{'A': 1} {'B': 2}
{'C': 3} {'D': 4}
>>> 

This does not rely on slicing which means it's more memory efficient and likely faster as well since the two sequences that zip is 'zipping' in this case are being generated on the fly via iter(data), meaning one pass instead of three passes (1 for the first slice, 1 for seconds slice, 1 for zip).

If for some reason your data was very large then you probably wouldn't want to construct a whole new list of tuples which zip returns just to loop through it once. In that case you could use itertools.izip in place of zip.

Upvotes: 2

AdamKG
AdamKG

Reputation: 14091

http://docs.python.org/2/library/itertools.html

Look for 'grouper', you'd use n=2.

import itertools
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 itertools.izip_longest(fillvalue=fillvalue, *args)

Upvotes: 1

rnbguy
rnbguy

Reputation: 1399

Use index to fetch two elements from the list.

testList = [{'2': 2}, {'3':3}, {'4':4}, {'5':5}]
for i in range(0,len(testList),2):
    print(testList[i],testList[i+1])

Upvotes: -1

Sukrit Kalra
Sukrit Kalra

Reputation: 34531

Use zip() here.

>>> testList = [{'2': 2}, {'3':3}, {'4':4}, {'5':5}]
>>> for i, j in zip(testList[::2], testList[1::2]):
        print i, j


{'2': 2} {'3': 3}
{'4': 4} {'5': 5}

Alternative (without using zip()):

for elem in range(0, len(testList), 2):
    firstDict, secondDict = testList[i], testList[i+1]

Upvotes: 3

ovgolovin
ovgolovin

Reputation: 13430

>>> L = [{'1A': 1},{'1B': 1},{'2A': 2}, {'2B': 2}]
>>> zip(*[iter(L)]*2)
[({'1A': 1}, {'1B': 1}), ({'2A': 2}, {'2B': 2})]

Upvotes: 2

Jon Clements
Jon Clements

Reputation: 142226

You can do this using zip with an iterator over the list:

>>> dicts = [{'1A': 1}, {'1B': 2}, {'2A': 3}, {'2B': 4}]
>>> for obj1, obj2 in zip(*[iter(dicts)]*2):
    print obj1, obj2


{'1A': 1} {'1B': 2}
{'2A': 3} {'2B': 4}

Upvotes: 6

Related Questions