python:在列表中穿插元素的最优雅方式
输入: 输出:python:在列表中穿插元素的最优雅方式,python,list,Python,List,输入: 输出: intersperse(666, ["once", "upon", "a", 90, None, "time"]) 最优雅的(读入:Pythonic)编写穿插的方法是什么?我会选择一个简单的生成器 ["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"] 然后你可以得到如下列表: def intersperse(val, sequence): first = True for item i
intersperse(666, ["once", "upon", "a", 90, None, "time"])
最优雅的(读入:Pythonic)编写
穿插的方法是什么?我会选择一个简单的生成器
["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]
然后你可以得到如下列表:
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
营救
-或-
一行中可以使用多少个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"]
如果您不想要尾随的666
,则返回reduce(…)[:-1]
那么:
>>> 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)
我自己会写一个生成器,但像这样:
from itertools import chain,izip_longest
def intersperse(x,y):
return list(chain(*izip_longest(x,[],fillvalue=y)))
另一个适用于序列的选项:
def joinit(iterable, delimiter):
it = iter(iterable)
yield next(it)
for x in it:
yield delimiter
yield x
[编辑]更正了以下代码:
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]
应该适用于列表或生成器。我现在刚想到这个,谷歌搜索看看是否有更好的。。。我想没有:-)
解决方案非常简单,只需使用:
从技术上讲,这个答案并不是“编写”intersprise
,而是从另一个库中使用它。但它可能会让其他人不必重新发明轮子。我相信与yield next(iterator)
或itertools.iterator\u magic()
one:)相比,这个看起来很好,也很容易掌握
您可以做的最基本、最简单的事情是:
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]
输出:
a = ['abc','def','ghi','jkl']
# my separator is : || separator ||
# hack is extra thing : --
'--|| separator ||--'.join(a).split('--')
我想到了这一点,但我不喜欢在列表的末尾切片,我可以将结果初始化为列表[0],但我必须首先检查列表是否为空。[][:-1]方便地返回[]使我免于那个问题。似乎到目前为止,生成器的答案是唯一一个没有使用切片的答案。我最喜欢这个:没有切片,没有做任何特定于迭代器的事情,比如调用len
。。这不是一款单品系列,但它看起来比单品系列更好(回到上一版本)@杰夫梅尔卡多:是的,谢谢你的评论(我想是你吗?)。它确实有效…@杰夫梅尔卡多:我知道。。。。同步问题;)但不确定这是否真的有效。。。这么多迭代器。。。。我喜欢你的解决方案:)但是知道不止一种方法(尽管Pythons的座右铭是只有一种;))很好。注意,chain
的参数扩展需要迭代所有的s
。这对于像intersperse(666,repeat(777))
这样的东西来说是一个大问题,生成器很好地回答了这个问题。你应该可以用链来解决这个问题。取而代之的是from_iterable(izip(…)
。@安德鲁:哦,我不知道。但现在我想起来有道理了。。。谢谢你,威尔在我的回答中提到这一点。是的,这比我的尝试要干净得多。恶心,这看起来是迄今为止最好的注意:第一个arg可以称为iterable
。可以只调用函数joinit()
。顺便说一句,您的解决方案的优点是它也适用于空序列(next()
引发StopIteration
,生成器joinseq()
立即返回)。我喜欢joinit
的双关语,意思是“加入它”和“加入它[erable]”@claudiu我喜欢你两年后回来指出:)最后一个666
不应该有小的改进:使用“operator.concat”而不是lambda。但是这非常低效,你为每个元素调用一个函数,并进行列表添加而不是追加/扩展这是O(n²);O(n)解决方案是非常可能的,而且更简单。对不起,我想我没有注意到问题是“用元素散布列表的最快方法?”。我不知道你可以做res[::2]=seq
。那真的很有趣。这很漂亮!我喜欢小列表的一行,但我建议使用更独特的分隔符看起来像是一根很普通的绳子,它会咬人的。请使用类似“$)($”的内容。
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']
def intersperse(items, delim):
i = iter(items)
return reduce(lambda x, y: x + [delim, y], i, [i.next()])
def intersperse(e, l):
return list(itertools.chain(*[(i, e) for i in l]))[0:-1]
>>> 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']
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]
a = ['abc','def','ghi','jkl']
# my separator is : || separator ||
# hack is extra thing : --
'--|| separator ||--'.join(a).split('--')
['abc','|| separator ||','def','|| separator ||','ghi','|| separator ||','jkl']