Is there a more elegant / pythonic way to express this design?

itemList = ["a","b","c","d","e","f","g","h"]
aa = "NULL"
bb = "NULL"
cc = "NULL"
for item in itemList:
    aa = bb
    bb = cc
    cc = item
    if aa == "NULL":
        continue
    print "%s_%s_%s" % (aa, bb, cc)
+1
source share
3 answers
>>> ['_'.join(itemList[i:i+3]) for i in range(len(itemList)-2)]
['a_b_c', 'b_c_d', 'c_d_e', 'd_e_f', 'e_f_g', 'f_g_h']

or if you insist on printing:

>>> for i in range(len(itemList)-2):
    print('_'.join(itemList[i:i+3]))
+9
source
import itertools
def windows(iterable, length=2):
    return itertools.izip(*(itertools.islice(it,n,None)
            for n,it in enumerate(itertools.tee(iterable,length))))

itemList = ["a","b","c","d","e","f","g","h"]
for group in windows(itemList,length=3):
    print('_'.join(group))

SilentGhost elegant list comprehension is better for this problem. But just to explain why I am not deleting this post:

One day you will want to create windows from an iterator that is not a list. Since you cannot take the length of the iterator without consuming it (and also, since some iterators can be infinite), and since taking slices from the iterator always returns new values, you cannot use list comprehension ['_'.join(itemList[i:i+3]) for i in range(len(itemList)-2)]in this case.

Then the function is windowsreally useful. For instance:

def itemList():
    for x in range(8):
        yield str(x)
for group in windows(itemList(),length=3):
    print('_'.join(group))

gives

0_1_2
1_2_3
2_3_4
3_4_5
4_5_6
5_6_7
+1
source

deque.

itemList = ["a","b","c","d","e","f","g","h"]
buffer = collections.deque(maxlen=3)
for item in itemList:
    buffer.append(item)
    if len(buffer) != 3:
        continue
    print "%s_%s_%s" % (buffer)

Python, , , .

0

All Articles