使用步长python列出一个列表项?

时间:2015-12-18 15:41:44

标签: python list iterator

给出输入列表

 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

7 个答案:

答案 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-itertoolstoolz

答案 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]