0

I want to make a function that can iterate through anything (n specified times) put in the parameter and generate with padding.

So lets say I have this function:

def generate_with_padding(tobeiterated, n, pad = None):
     ...

If I call using a string lets say: generate_with_padding('abcdefg', 10, '?')

I would like it to return:

a
b
c
d
e
f
g
?
?
?

I don't want to use indexing because I want to iterate through generators too. How can I approach this? Maybe I can use next()?

user2559679
  • 87
  • 1
  • 7

4 Answers4

2

itertools is the best answer. You can do it like this

from itertools import repeat, chain, islice

def generate_with_padding(tobeiterated, n, pad = None):
    return islice(chain(tobeiterated, repeat(pad)), n)

Few tests

def generator():
    for i in xrange(1, 6):
        yield i

print list(generate_with_padding("abcd", 10, "?"))
print list(generate_with_padding([1, 2], 5))
print list(generate_with_padding(generator(), 10, 0))

Output

['a', 'b', 'c', 'd', '?', '?', '?', '?', '?', '?']
[1, 2, None, None, None]
[1, 2, 3, 4, 5, 0, 0, 0, 0, 0]

Note: If you want the output to be a list, instead of an iterator, you can replace return statement, like this

return list(islice(chain(tobeiterated, repeat(pad)), n))
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
0

This is already built into the itertools module and thus works with all iterables, including generators:

>>> import itertools
>>> a = "abcdefg"
>>> [item for item, index in itertools.izip_longest(a, xrange(10), fillvalue="?")]
['a', 'b', 'c', 'd', 'e', 'f', 'g', '?', '?', '?']

If you use () instead of [], you get a generator instead of a list (which I used here for visualization).

Tim Pietzcker
  • 328,213
  • 58
  • 503
  • 561
  • Interesting, but I think I have to prefer @thefourtheye's approach - it seems like a more direct statement of the desired effect. – Karl Knechtel Feb 05 '14 at 07:10
0

How about just keeping a count inside a foreach loop? I am not sure if this violates your constraint about "using indices", but it does achieve the behavior you desire, and it works with generators.

def generate_with_padding(tobeiterated, n, pad = None):
     count = 0
     for x in tobeiterated:
         count = count + 1
         yield x
     for _ in xrange(n - count):
         yield pad 

For example, the following generates the output you want:

for i in generate_with_padding('abcdefg', 10, '?'):
   print i
merlin2011
  • 71,677
  • 44
  • 195
  • 329
  • I would avoid using `_` as a variable name. – thefourtheye Feb 05 '14 at 06:40
  • Normally I would agree, but I use it when I want to make the point that the variable is unused and doesn't matter. See this question : http://stackoverflow.com/questions/5893163/underscore-in-python – merlin2011 Feb 05 '14 at 07:11
0

You can use ljust or rjust based on your padding orientation. Basic syntax is:

str="Padding String";
s= str.ljust(20,'?');
l=list(s)
print(l)

Output: ['P', 'a', 'd', 'd', 'i', 'n', 'g', ' ', 'S', 't', 'r', 'i', 'n', 'g', '?', '?', '?', '?', '?', '?']

You can pass your parameters to ljust function. This is out of box, you don't need to import anything.

Amit Shakya
  • 1,396
  • 12
  • 27