给出输入列表
l = [1 2 3 4 5 6 7 8 9 10]
和组大小grp和步骤
grp = 3; step = 2
我想返回一份清单。注意最后的重复
1 2 3
3 4 5
5 6 7
7 8 9
9 10 1
或如果
grp= 4; step = 2
输出应为
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
这是我提出的代码,它没有做循环的事情。 但是想知道是否存在更小或更简单的解决方案
def grouplist(l,grp,step):
oplist = list()
for x in range(0,len(l)):
if (x+grp<len(l)):
oplist.append(str(l[x:x+grp]))
return oplist
答案 0 :(得分:3)
您可以利用xrange或range中的step函数,具体取决于您使用的python版本。然后按照列表的长度来回绕mod,就像这样
ssh root@[ipaddress] "dd if=/dev/sda1 | gzip -1 -" | dd of=outputfile.gz
答案 1 :(得分:2)
def grouplist(L, grp, step):
starts = range(0, len(L), step)
stops = [x + grp for x in starts]
groups = [(L*2)[start:stop] for start, stop in zip(starts, stops)]
return groups
def tabulate(groups):
print '\n'.join(' '.join(map(str, row)) for row in groups)
print
示例输出:
>>> tabulate(grouplist(range(1,11), 3, 2))
1 2 3
3 4 5
5 6 7
7 8 9
9 10 1
>>> tabulate(grouplist(range(1,11), 4, 2))
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
9 10 1 2
答案 2 :(得分:2)
使用deque:
from itertools import islice
from collections import deque
def grps(l, gps, stp):
d = deque(l)
for i in range(0, len(l), stp):
yield list(islice(d, gps))
d.rotate(-stp)
输出:
In [7]: l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
In [8]: list(grps(l, 3, 2))
Out[8]: [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10, 1]]
In [9]: list(grps(l, 4, 2))
Out[9]: [[1, 2, 3, 4], [3, 4, 5, 6], [5, 6, 7, 8], [7, 8, 9, 10], [9, 10, 1, 2]]
你也可以加入产生islice对象并决定你想在外面做什么:
def grps(l, gps, stp):
d = deque(l)
for i in range(0, len(l), stp):
yield islice(d, gps)
d.rotate(-stp)
输出:
In [11]: for gp in grps(l, 3,2):
....: print(" ".join(map(str,gp)))
....:
1 2 3
3 4 5
5 6 7
7 8 9
9 10 1
或仅使用模数:
def grps(l, gps, stp):
ln = len(l)
for i in range(0, len(l), stp):
yield (l[j % ln] for j in range(i, i + gps))
for gp in grps(l, 4, 2):
print(" ".join(map(str, gp)))
答案 3 :(得分:2)
[(l+l)[x:x+grp] for x,_ in list(enumerate(l))[::step]]
在一行中诀窍
答案 4 :(得分:1)
包iteration_utilities
1 有一个用于此类滑动窗口提取的函数successive
:
from iteration_utilities import successive
from itertools import chain, islice, starmap
def wrapped_and_grouped_with_step(seq, groupsize, step, formatting=False):
padded = chain(seq, seq[:step-1])
grouped = successive(padded, groupsize)
stepped = islice(grouped, None, None, step)
if formatting:
inner_formatted = starmap(('{} '*groupsize).strip().format, stepped)
outer_formatted = '\n'.join(inner_formatted)
return outer_formatted
else:
return stepped
将此应用于您的示例:
>>> list(wrapped_and_grouped_with_step(l, 3, 2))
[(1, 2, 3), (3, 4, 5), (5, 6, 7), (7, 8, 9), (9, 10, 1)]
>>> list(wrapped_and_grouped_with_step(l, 4, 2))
[(1, 2, 3, 4), (3, 4, 5, 6), (5, 6, 7, 8), (7, 8, 9, 10)]
>>> print(wrapped_and_grouped_with_step(l, 3, 2, formatting=True))
1 2 3
3 4 5
5 6 7
7 8 9
9 10 1
>>> print(wrapped_and_grouped_with_step(l, 4, 2, formatting=True))
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
该套餐还包括便利类ManyIterables
:
>>> from iteration_utilities import ManyIterables
>>> step, groupsize = 2, 4
>>> print(ManyIterables(l, l[:step-1])
... .chain()
... .successive(groupsize)
... [::step]
... .starmap(('{} '*groupsize).strip().format)
... .as_string('\n'))
1 2 3 4
3 4 5 6
5 6 7 8
7 8 9 10
请注意,这些操作是基于生成器的,因此评估将推迟到您迭代它(例如通过创建list
)。
请注意,我是iteration_utilities的作者。还有其他几个包也提供类似功能,即more-itertools
和toolz
答案 5 :(得分:0)
这是另一种解决方案,它在扫描时不使用列表中的索引。相反,它会保存要重复的遇到的元素,并将它们与后面的元素连接起来。
def grplst(l, grp, stp):
ret = []
saved = []
curstp = 0
dx = grp - stp
for el in l:
curstp += 1
if curstp <= stp:
ret.append(el)
else:
saved.append(el)
if curstp >= grp:
yield ret+saved
ret = saved
saved = []
curstp = dx
yield ret+l[:dx]
l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for g in grplst(l, 3, 2):
print(g)
for g in grplst(l, 4, 2):
print(g)
产生
[1, 2, 3]
[3, 4, 5]
[5, 6, 7]
[7, 8, 9]
[9, 10, 1]
[1, 2, 3, 4]
[3, 4, 5, 6]
[5, 6, 7, 8]
[7, 8, 9, 10]
[9, 10, 1, 2]
答案 6 :(得分:0)
从版本2.5开始,more_itertools.windowed
支持step
关键字。
> pip install more_itertools
应用:
import itertools as it
import more_itertools as mit
def grouplist(l, grp, step):
"""Yield a finite number of windows."""
iterable = it.cycle(l)
cycled_windows = mit.windowed(iterable, grp, step=step)
last_idx = grp - 1
for i, window in enumerate(cycled_windows):
yield window
if last_idx >= len(l) - 1:
break
last_idx += (i * step)
list(grouplist(l, 3, 2))
# Out: [(1, 2, 3), (3, 4, 5), (5, 6, 7), (7, 8, 9), (9, 10, 1)]
list(grouplist(l, 4, 2))
# Out: [(1, 2, 3, 4), (3, 4, 5, 6), (5, 6, 7, 8), (7, 8, 9, 10)]
list(mit.flatten(grouplist(l, 3, 2)))) # optional
# Out: [1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 1]