我喜欢unutbu 的答案,但不喜欢嵌套风格,所以我重写了它。当我在那里时,我注意到排序不稳定,所以我使用operator.itemgetter
.
我也替换itertools.count
为,enumerate
因为它更直观。作为奖励,它对于大输入也应该更准确,尽管我还没有测试过。
import itertools
import operator
def distribute(sequence):
"""
Enumerate the sequence evenly over the interval (0, 1).
>>> list(distribute('abc'))
[(0.25, 'a'), (0.5, 'b'), (0.75, 'c')]
"""
m = len(sequence) + 1
for i, x in enumerate(sequence, 1):
yield i/m, x
def intersperse(*sequences):
"""
Evenly intersperse the sequences.
Based on https://stackoverflow.com/a/19293603/4518341
>>> list(intersperse(range(10), 'abc'))
[0, 1, 'a', 2, 3, 4, 'b', 5, 6, 7, 'c', 8, 9]
>>> list(intersperse('XY', range(10), 'abc'))
[0, 1, 'a', 2, 'X', 3, 4, 'b', 5, 6, 'Y', 7, 'c', 8, 9]
>>> ''.join(intersperse('hlwl', 'eood', 'l r!'))
'hello world!'
"""
distributions = map(distribute, sequences)
get0 = operator.itemgetter(0)
for _, x in sorted(itertools.chain(*distributions), key=get0):
yield x
请注意,与您的第二个示例有一个不同之处,即'b'
下移'c'
的位置:
>>> list(intersperse(range(1, 6), 'abc'))
[1, 'a', 2, 3, 'b', 4, 'c', 5]