子列表列表提供了子列表及其元素的数量

时间:2014-07-11 11:52:39

标签: python python-2.7

def listOfLists(ntimes,lines,list_val):
    a = []
    i = 0
    j = 0

    if ntimes >= lines:
        inner_loop = ntimes
        outer_loop = lines
    else:
        inner_loop = lines
        outer_loop = ntimes

    while i < outer_loop:
        while j < inner_loop+i:
            if (j*inner_loop-i < len(list_val)):
                a.append(list_val[j*inner_loop-i])
                j=j+1

            else:
                j=1
                a.append(list_val[j*inner_loop-i])
                break

        j = i+1
        i = i+1
        print a
    y = [a[x:x+ntimes] for x in range(0, len(a), ntimes)]
    print y

我喜欢的是一个包含子列表的列表,其元素数量是ntimes,行数是子列表的数量。如果输入类似listOfLists(2,3,[1,2,3,4,5,6]),则输出应为:

[[1,4],[2,5],[3,6]]

我目前正在:

[[1, 4], [4, 3], [6, 3]]

如何修复代码才能实现此目的?

3 个答案:

答案 0 :(得分:1)

使用grouper recipe from itertools

>>> L
[1, 2, 3, 4, 5, 6]
>>> zip(*grouper(L, 3))
[(1, 4), (2, 5), (3, 6)]

拉链为你提供了元组。如果由于某种原因需要列表,请进行理解:

>>> [list(t) for t in _]
[[1, 4], [2, 5], [3, 6]]

答案 1 :(得分:0)

你可以这样做:

def listOfLists(ntimes, lines, list_val):
    return zip(*zip(*(iter(list_val),) * lines))

输出:

[(1, 4), (2, 5), (3, 6)]

答案 2 :(得分:0)

如果lst的长度乘以lines

,则以下代码有效
>>> lst = [1, 2, 3, 4, 5, 6]
>>> lines = 3
>>> zip(*zip(*[iter(lst)]*lines))
[(1, 4), (2, 5), (3, 6)]

这种魔法源自wim提到的grouper

解释魔法

有一个值列表

>>> lst = [1,2,3,4,5,6]

在列表值上创建一个迭代器:

>>> iter(lst)
<listiterator at 0x7f641480d490>

注意:迭代器能够逐项生成项目,在这种情况下,它已准备好从lst

逐项生成

创建包含一个迭代器的列表:

>>> [iter(lst)]
[<listiterator at 0x7f641480d750>]

列表是可变结构,因此即使从多个变量引用,它仍然引用 内存中的数据结构相同。如果这些引用中的任何一个使用迭代器,迭代器 被修改为对此列表的所有引用。

现在创建列表的乘法,乘以预期行数。

>>> [iter(lst)] * 3
[<listiterator at 0x7f641480dc50>,
 <listiterator at 0x7f641480dc50>,
 <listiterator at 0x7f641480dc50>]

注意,所有迭代器都显示相同的地址,此列表中的所有三个项都是引用 到同一个迭代器。

现在是弗兰步骤,将所有内容压缩起来:

>>> zip(*[iter(lst)] * 3)
[(1, 2, 3), (4, 5, 6)]

可以改写为:

zip(*[<listiterator at 0x7f641480dc50>, <listiterator at 0x7f641480dc50>, <listiterator at 0x7f641480dc50>])

将(通过*解除引用)转换为:

>>> zip(<listiterator at 0x7f641480dc50>, <listiterator at 0x7f641480dc50>, <listiterator at 0x7f641480dc50>)
[(1, 2, 3), (4, 5, 6)]

zip的工作方式,它要求每个迭代器提供一个值并创建一个元组 从这3个值。诀窍是,每个来自迭代器的值的请求都会从中消耗它 所有引用,所以下次它询问任何迭代器时,下一个值将会到来。

最后一步是做最后的压缩:

zip(*[(1, 2, 3), (4, 5, 6)])

转换为:

zip((1, 2, 3), (4, 5, 6))

我们得到了结果:

[(1, 4), (2, 5), (3, 6)]