Input:
intersperse(666, ["once", "upon", "a", 90, None, "time"])
Output:
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
What's the most elegant (read: Pythonic) way to write intersperse
?
什么是最优雅的(阅读:Pythonic)写散布的方式?
12 个解决方案
#1
27
I would have written a generator myself, but like this:
我自己会写一个发电机,但是这样:
def joinit(iterable, delimiter):
it = iter(iterable)
yield next(it)
for x in it:
yield delimiter
yield x
#2
13
itertools
to the rescue
- or -
How many itertools functions can you use in one line?
itertools拯救 - 或者 - 你可以在一行中使用多少个itertools函数?
from itertools import chain, izip, repeat, islice
def intersperse(delimiter, seq):
return islice(chain.from_iterable(izip(repeat(delimiter), seq)), 1, None)
Usage:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"])
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
#3
8
Another option that works for sequences:
另一个适用于序列的选项:
def intersperse(seq, value):
res = [value] * (2 * len(seq) - 1)
res[::2] = seq
return res
#4
3
I would go with a simple generator.
我会选择一个简单的发电机。
def intersperse(val, sequence):
first = True
for item in sequence:
if not first:
yield val
yield item
first = False
and then you can get your list like so:
然后你就可以得到你的清单:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"]))
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
alternatively you could do:
或者你可以这样做:
def intersperse(val, sequence):
for i, item in enumerate(sequence):
if i != 0:
yield val
yield item
I'm not sure which is more pythonic
我不确定哪个更pythonic
#5
2
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]
[Edit] Corrected code below:
[编辑]修改后的代码如下:
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']
#6
1
How about:
from itertools import chain,izip_longest
def intersperse(x,y):
return list(chain(*izip_longest(x,[],fillvalue=y)))
#7
1
Dunno if it's pythonic, but it's pretty simple:
Dunno,如果它是pythonic,但它很简单:
def intersperse(elem, list):
result = []
for e in list:
result.extend([e, elem])
return result[:-1]
#8
1
Solution is trivial using more_itertools.intersperse
:
使用more_itertools.intersperse解决方案是微不足道的:
>>> from more_itertools import intersperse
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"]))
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
Technically, this answer isn't "writing" intersperse
, it's just using it from another library. But it might save others from having to reinvent the wheel.
从技术上讲,这个答案不是“写”散布,它只是从另一个库中使用它。但它可能会让其他人不必重新发明*。
#9
0
This works:
>>> 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)
If you don't want a trailing 666
, then return reduce(...)[:-1]
.
如果你不想要尾随666,那么返回reduce(...)[: - 1]。
#10
0
I just came up with this now, googled to see if there was something better... and IMHO there wasn't :-)
我现在想出了这个,用谷歌搜索看看是否有更好的东西......而恕我直言那里没有:-)
def intersperse(e, l):
return list(itertools.chain(*[(i, e) for i in l]))[0:-1]
#11
0
I believe this one looks pretty nice and easy to grasp compared to the yield next(iterator)
or itertools.iterator_magic()
one :)
我认为与yield next(iterator)或itertools.iterator_magic()之一相比,这个看起来相当不错且容易掌握:)
def list_join_seq(seq, sep):
for i, elem in enumerate(seq):
if i > 0: yield sep
yield elem
print(list(list_join_seq([1, 2, 3], 0))) # [1, 0, 2, 0, 3]
#12
-1
def intersperse(items, delim):
i = iter(items)
return reduce(lambda x, y: x + [delim, y], i, [i.next()])
Should work for lists or generators.
应该适用于列表或生成器。
#1
27
I would have written a generator myself, but like this:
我自己会写一个发电机,但是这样:
def joinit(iterable, delimiter):
it = iter(iterable)
yield next(it)
for x in it:
yield delimiter
yield x
#2
13
itertools
to the rescue
- or -
How many itertools functions can you use in one line?
itertools拯救 - 或者 - 你可以在一行中使用多少个itertools函数?
from itertools import chain, izip, repeat, islice
def intersperse(delimiter, seq):
return islice(chain.from_iterable(izip(repeat(delimiter), seq)), 1, None)
Usage:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"])
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
#3
8
Another option that works for sequences:
另一个适用于序列的选项:
def intersperse(seq, value):
res = [value] * (2 * len(seq) - 1)
res[::2] = seq
return res
#4
3
I would go with a simple generator.
我会选择一个简单的发电机。
def intersperse(val, sequence):
first = True
for item in sequence:
if not first:
yield val
yield item
first = False
and then you can get your list like so:
然后你就可以得到你的清单:
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"]))
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
alternatively you could do:
或者你可以这样做:
def intersperse(val, sequence):
for i, item in enumerate(sequence):
if i != 0:
yield val
yield item
I'm not sure which is more pythonic
我不确定哪个更pythonic
#5
2
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]
[Edit] Corrected code below:
[编辑]修改后的代码如下:
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']
#6
1
How about:
from itertools import chain,izip_longest
def intersperse(x,y):
return list(chain(*izip_longest(x,[],fillvalue=y)))
#7
1
Dunno if it's pythonic, but it's pretty simple:
Dunno,如果它是pythonic,但它很简单:
def intersperse(elem, list):
result = []
for e in list:
result.extend([e, elem])
return result[:-1]
#8
1
Solution is trivial using more_itertools.intersperse
:
使用more_itertools.intersperse解决方案是微不足道的:
>>> from more_itertools import intersperse
>>> list(intersperse(666, ["once", "upon", "a", 90, None, "time"]))
['once', 666, 'upon', 666, 'a', 666, 90, 666, None, 666, 'time']
Technically, this answer isn't "writing" intersperse
, it's just using it from another library. But it might save others from having to reinvent the wheel.
从技术上讲,这个答案不是“写”散布,它只是从另一个库中使用它。但它可能会让其他人不必重新发明*。
#9
0
This works:
>>> 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)
If you don't want a trailing 666
, then return reduce(...)[:-1]
.
如果你不想要尾随666,那么返回reduce(...)[: - 1]。
#10
0
I just came up with this now, googled to see if there was something better... and IMHO there wasn't :-)
我现在想出了这个,用谷歌搜索看看是否有更好的东西......而恕我直言那里没有:-)
def intersperse(e, l):
return list(itertools.chain(*[(i, e) for i in l]))[0:-1]
#11
0
I believe this one looks pretty nice and easy to grasp compared to the yield next(iterator)
or itertools.iterator_magic()
one :)
我认为与yield next(iterator)或itertools.iterator_magic()之一相比,这个看起来相当不错且容易掌握:)
def list_join_seq(seq, sep):
for i, elem in enumerate(seq):
if i > 0: yield sep
yield elem
print(list(list_join_seq([1, 2, 3], 0))) # [1, 0, 2, 0, 3]
#12
-1
def intersperse(items, delim):
i = iter(items)
return reduce(lambda x, y: x + [delim, y], i, [i.next()])
Should work for lists or generators.
应该适用于列表或生成器。