Input:
intersperse(666, ["once", "upon", "a", 90, None, "time"])
Вывод:
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
Какой самый элегантный (читай: Pythonic) способ написать intersperse
?
Input:
intersperse(666, ["once", "upon", "a", 90, None, "time"])
Вывод:
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
Какой самый элегантный (читай: Pythonic) способ написать intersperse
?
Я бы написал генератор сам, но вот так:
def joinit(iterable, delimiter):
it = iter(iterable)
yield next(it)
for x in it:
yield delimiter
yield x
itertools
на помощь
- или -
Сколько функций itertools вы можете использовать в одной строке?
from itertools import chain, izip, repeat, islice
def intersperse(delimiter, seq):
return islice(chain.from_iterable(izip(repeat(delimiter), seq)), 1, None)
Использование:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"])
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
Другая опция, которая работает для последовательностей:
def intersperse(seq, value):
res = [value] * (2 * len(seq) - 1)
res[::2] = seq
return res
Я бы пошел с простым генератором.
def intersperse(val, sequence):
first = True
for item in sequence:
if not first:
yield val
yield item
first = False
а затем вы можете получить свой список следующим образом:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"]))
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
альтернативно вы можете сделать:
def intersperse(val, sequence):
for i, item in enumerate(sequence):
if i != 0:
yield val
yield item
Я не уверен, что больше pythonic
def intersperse(word,your_list):
x = [j for i in your_list for j in [i,word]]
>>> intersperse(666, ["once", "upon", "a", 90, None, "time"])
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time', 666]
[Изменить] Исправленный код ниже:
def intersperse(word,your_list):
x = [j for i in your_list for j in [i,word]]
x.pop()
return x
>>> intersperse(666, ["once", "upon", "a", 90, None, "time"])
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
Не знаю, если это pythonic, но это довольно просто:
def intersperse(elem, list):
result = []
for e in list:
result.extend([e, elem])
return result[:-1]
Как насчет:
from itertools import chain,izip_longest
def intersperse(x,y):
return list(chain(*izip_longest(x,[],fillvalue=y)))
Это работает:
>>> def intersperse(e, l):
... return reduce(lambda x,y: x+y, zip(l, [e]*len(l)))
>>> intersperse(666, ["once", "upon", "a", 90, None, "time"])
('once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time', 666)
Если вам не нужен конечный 666
, тогда return reduce(...)[:-1]
.
Я только что придумал это сейчас, googled, чтобы увидеть, есть ли что-то лучше... и IMHO не было: -)
def intersperse(e, l):
return list(itertools.chain(*[(i, e) for i in l]))[0:-1]
def intersperse(items, delim):
i = iter(items)
return reduce(lambda x, y: x + [delim, y], i, [i.next()])
Должен работать для списков или генераторов.