alvas
alvas

Reputation: 122142

How to access 2 list at a time while looking ahead with izip_longest? -Python

The code below only access one list at a time and looking ahead 1 element each loop:

from itertools import izip_longest

alist = ['foo','bar','duh']
blist = ['ofo','ardavak','dot','dotdat']

for i, plus1 in izip_longest(alist, alist[1:], fillvalue=None):
  iplus1 = i + plus1 if plus1 is not None else ""

for j, plus1 in izip_longest(blist, blist[1:], fillvalue=None):
  jplus1 = j + plus1 if plus1 is not None else ""

How do i look ahead 1 element each loop for 2 list simultaneously? something like:

for (i,plus1),(j,plus1) in izip(izip_longest(alist, alist[1:], fillvalue=None), izip_longest(blist, blist[1:], fillvalue=None)):
  print i,j
  print i,j+plus1
  print i+plus1,j
  print i+plus1,j+plus1

The desired output should look like this:

foo ofo
foo ofoardavak
foobar ofo
foobar ofoardvak
bar ardavak
bar ardavakdot
barduh ardavak
barduh ardavakdot
duh dot
duh dotdotdat
 dot
 dotdotdat
 dotdat

 dotdat

Upvotes: 1

Views: 88

Answers (2)

root
root

Reputation: 80386

from itertools import product,izip,izip_longest

def pairs(lst):
    i = iter(lst)
    prev = i.next()
    for item in i:
        yield prev, prev+item   
        prev = item

[list(product(*v)) for v in izip(*map(pairs,
                   izip(*izip_longest(alist,blist,fillvalue=''))))]

out:

[[('foo', 'ofo'),
  ('foo', 'ofoardavak'),
  ('foobar', 'ofo'),
  ('foobar', 'ofoardavak')],
 [('bar', 'ardavak'),
  ('bar', 'ardavakdot'),
  ('barduh', 'ardavak'),
  ('barduh', 'ardavakdot')],
 [('duh', 'dot'), ('duh', 'dotdotdat'), ('duh', 'dot'), ('duh', 'dotdotdat')]]

Upvotes: 1

Thorsten Kranz
Thorsten Kranz

Reputation: 12765

Maybe something like:

from itertools import izip_longest

alist = ['foo','bar','duh']
blist = ['ofo','ardavak','dot','dotdat']

combined_list = list(izip_longest(alist, blist, fillvalue=""))

for (i,j),(iplus1,jplus1) in izip_longest(combined_list, combined_list[1:], fillvalue=("", "")):
    print i,j
    print i,j+jplus1
    print i+iplus1,j
    print i+iplus1,j+jplus1

But be aware that zip() only takes min(len(alist),len(blist)) elements, i.e., the returned list is truncated in length to the length of the shortest argument sequence.

Upvotes: 1

Related Questions