简体   繁体   English

python:用元素散布列表的最优雅方式

[英]python: most elegant way to intersperse a list with an element

Input:输入:

intersperse(666, ["once", "upon", "a", 90, None, "time"])

Output: Output:

["once", 666, "upon", 666, "a", 666, 90, 666, None, 666, "time"]

What's the most elegant (read: Pythonic) way to write intersperse ?编写intersperse的最优雅(阅读:Pythonic)方式是什么?

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

itertools to the rescue itertools来救援
- or - - 或者 -
How many itertools functions can you use in one line?一行可以使用多少个 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"]

Another option that works for sequences:另一个适用于序列的选项:

def intersperse(seq, value):
    res = [value] * (2 * len(seq) - 1)
    res[::2] = seq
    return res

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.从技术上讲,这个答案不是“写作” intersperse ,它只是从另一个库中使用它。 But it might save others from having to reinvent the wheel.但这可能会使其他人不必重新发明轮子。

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

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']

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]

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() 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]

Dunno if it's pythonic, but it's pretty simple:不知道它是否是 pythonic,但它非常简单:

def intersperse(elem, list):
    result = []
    for e in list:
      result.extend([e, elem])
    return result[:-1]

How about:怎么样:

from itertools import chain,izip_longest

def intersperse(x,y):
     return list(chain(*izip_longest(x,[],fillvalue=y)))

The basic and easy you could do is:您可以做的基本且简单的事情是:

a = ['abc','def','ghi','jkl']

# my separator is : || separator ||
# hack is extra thing : --

'--|| separator ||--'.join(a).split('--')

output:输出:

['abc','|| separator ||','def','|| separator ||','ghi','|| separator ||','jkl']

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 ,则return reduce(...)[:-1]

Seems general and efficient:似乎通用且高效:

def intersperse(lst, fill=...):
    """
    >>> list(intersperse([1,2,3,4]))
    [1, Ellipsis, 2, Ellipsis, 3, Ellipsis, 4]
    """
    return chain(*zip(lst[:-1], repeat(fill)), [lst[-1]])

You can use Python's list comprehension:您可以使用 Python 的列表理解:

def intersperse(iterable, element):
    return [iterable[i // 2] if i % 2 == 0 else element for i in range(2 * len(iterable) - 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.应该适用于列表或生成器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 最优雅的方法来计算Python中作业列表的完成时间 - Most elegant way to calculate completion times for a list of jobs in Python Python 2中具有任意长度列表的.format()格式化字符串的最优雅方法? - Most elegant way to .format() formatted string with arbitrary length list in Python 2? 最优雅的方式来分离基于模式的列表(Python) - Most elegant way to separate list based on pattern (Python) 最优雅的方式来计算列表中的整数 - Most elegant way to count integers in a list 在 Python 中配置 class 的最优雅方式? - Most elegant way to configure a class in Python? 最优雅的(pythonic)方式来获取列表列表中的第 i 个元素,并创建这些第 i 个元素的列表 - Most programmatically elegant (pythonic) way to take ith element of list of lists of lists, and create lists of these ith elements 检查数字是否在范围列表中并输出值的最优雅的方法 - Most elegant way to check if number is in a list of ranges and output a value 查找元素文本列表的最有效方法 Selenium Python - Most efficient way to find list of element text Selenium Python 在python中在命令上运行并行任务的最优雅的方法? - Most elegant way to run parallel tasks on command in python? 在Python中格式化多行字符串的最优雅方式 - Most elegant way to format multi-line strings in Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM