maininformer
maininformer

Reputation: 1077

zip multiple values with single value

I have a list:

ave=['Avg']

and another one:

range(0,24)

How do I zip them so I will have:

[0,'Avg',1,'Avg',....23,'Avg']

It is preferred not to have each entry in brackets ie

[[0,'Avg'],[...]]

since I would later want to make that list into a CSV.

I know I could do it with a simple loop, but is there a more clean-cut way? a function maybe?

Upvotes: 4

Views: 5656

Answers (6)

Brent Newey
Brent Newey

Reputation: 4509

Here's a fun solution:

from operator import add
reduce(add, zip(range(0, 24), ['Avg']*24))

Upvotes: 1

Jan Vlcinsky
Jan Vlcinsky

Reputation: 44102

Using generator

Generator is a function, which does not return single result, but can yields multiple ones during whatever run it uses.

Having a function gen as follows:

def gen(itm, nums):
    for num in nums:
        yield num
        yield itm

>>> g = gen("Avg", range(0, 4))
>>> list(g)
[0, 'Avg', 1, 'Avg', 2, 'Avg', 3, 'Avg']

The list function forced the g generator instance to iterate through all available values until there is no more items to yield and return them in a list.

Consuming from generator by next()

You can use the generator also in alternative ways using next, getting values just one by one:

>>> g = gen("Avg", range(0, 4))
>>> g.next()
0
>>> g.next()
'Avg'
>>> g.next()
1
>>> g.next()
'Avg'
>>> g.next()
2
>>> g.next()
'Avg'
>>> g.next()
3
>>> g.next()
'Avg'
>>> g.next()
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-17-d7e53364a9a7> in <module>()
----> 1 g.next()

StopIteration: 

Note, that we get StopIteration exception when there is no more values to yield.

Another important detail is, that a generator has it's internal state and you have to initialize it to get values again from the first to the last one. Exhausted instance of generator will not yield any more values.

Upvotes: 2

user2555451
user2555451

Reputation:

Using itertools.chain.from_iterable and itertools.izip_longest:

>>> from itertools import chain, izip_longest
>>> ave = ['Avg']
>>> r = range(0,24)
>>> list(chain.from_iterable(izip_longest(r, ave, fillvalue=ave[0])))
[0, 'Avg', 1, 'Avg', 2, 'Avg', 3, 'Avg', 4, 'Avg', 5, 'Avg', 6, 'Avg', 7, 'Avg', 8, 'Avg', 9, 'Avg', 10, 'Avg', 11, 'Avg', 12, 'Avg', 13, 'Avg', 14, 'Avg', 15, 'Avg', 16, 'Avg', 17, 'Avg', 18, 'Avg', 19, 'Avg', 20, 'Avg', 21, 'Avg', 22, 'Avg', 23, 'Avg']
>>>

Without importing, using a list comprehension would be a slightly less efficient but still workable solution:

>>> ave = ['Avg']
>>> r = range(0,24)
>>> [y for x in r for y in (x, ave[0])]
[0, 'Avg', 1, 'Avg', 2, 'Avg', 3, 'Avg', 4, 'Avg', 5, 'Avg', 6, 'Avg', 7, 'Avg', 8, 'Avg', 9, 'Avg', 10, 'Avg', 11, 'Avg', 12, 'Avg', 13, 'Avg', 14, 'Avg', 15, 'Avg', 16, 'Avg', 17, 'Avg', 18, 'Avg', 19, 'Avg', 20, 'Avg', 21, 'Avg', 22, 'Avg', 23, 'Avg']
>>>

Upvotes: 4

iruvar
iruvar

Reputation: 23364

Another option

 ave = ['Ave']
 m = range(24)
 [a for b in [(x, ave[0]) for x in m] for a in b]
 [0, 'Ave', 1, 'Ave', 2, 'Ave', 3, 'Ave', 4, 'Ave', 5, 'Ave', 6, 'Ave', 7, 'Ave', 8, 'Ave', 9, '

Upvotes: 1

timgeb
timgeb

Reputation: 78690

I think a loop like this is clean enough:

ave=['Avg']
lst = []
for x in range(24):
    lst.extend((x,ave[0]))

lst:

>>> lst
[0, 'Avg', 1, 'Avg', 2, 'Avg', 3, 'Avg', 4, 'Avg', 5, 'Avg', 6, 'Avg', 7, 'Avg', 8, 'Avg', 9, 'Avg', 10, 'Avg', 11, 'Avg', 12, 'Avg', 13, 'Avg', 14, 'Avg', 15, 'Avg', 16, 'Avg', 17, 'Avg', 18, 'Avg', 19, 'Avg', 20, 'Avg', 21, 'Avg', 22, 'Avg', 23, 'Avg']

Upvotes: 5

Platinum Azure
Platinum Azure

Reputation: 46183

It's easy enough to get the pairings as you noted, but you can then use itertools.chain() to unwrap the pairings:

from itertools import chain

fields = ['Avg']
indexes = range(0, 24)

groups = [[i] + fields for i in indexes]

flat_list = list(chain.from_iterable(groups))

Upvotes: 4

Related Questions