在python中将平面列表转换为列表列表

在python中将平面列表转换为列表列表,python,list,Python,List,有人可能会想做与平铺列表相反的事情:我想知道如何将平铺列表转换为列表列表 在numpy中,您可以执行以下操作: >>> a=numpy.arange(9) >>> a.reshape(3,3) >>> a array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) >>> Mylist ['a', 'b', 'c', 'd', 'e', 'f'] >>> newList

有人可能会想做与平铺列表相反的事情:我想知道如何将平铺列表转换为列表列表

在numpy中,您可以执行以下操作:

>>> a=numpy.arange(9)
>>> a.reshape(3,3)
>>> a
array([[0, 1, 2],
   [3, 4, 5],
   [6, 7, 8]])
>>> Mylist
['a', 'b', 'c', 'd', 'e', 'f']
>>> newList = []
for i in range(0,len(Mylist),2):
...     newList.append(Mylist[i], Mylist[i+1])
>>> newList 
[['a', 'b'], ['c', 'd'], ['e', 'f']]
我想知道你是怎么做的,我通常的解决办法是:

>>> a=numpy.arange(9)
>>> a.reshape(3,3)
>>> a
array([[0, 1, 2],
   [3, 4, 5],
   [6, 7, 8]])
>>> Mylist
['a', 'b', 'c', 'd', 'e', 'f']
>>> newList = []
for i in range(0,len(Mylist),2):
...     newList.append(Mylist[i], Mylist[i+1])
>>> newList 
[['a', 'b'], ['c', 'd'], ['e', 'f']]
有没有更“蟒蛇式”的方法

>>> l = ['a', 'b', 'c', 'd', 'e', 'f']
>>> zip(*[iter(l)]*2)
[('a', 'b'), ('c', 'd'), ('e', 'f')]
正如@Lattyware所指出的,只有当
zip
函数每次返回元组时,每个参数中都有足够的项时,这种方法才有效。如果其中一个参数的项目少于其他参数,则项目将被切断,例如

>>> l = ['a', 'b', 'c', 'd', 'e', 'f','g']
>>> zip(*[iter(l)]*2)
[('a', 'b'), ('c', 'd'), ('e', 'f')]
如果是这种情况,那么最好使用@Sven Marnach的解决方案


这通常是使用以下位置的石斑鱼配方完成的:

例如:

>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> list(grouper(2, my_list))
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', None)]

如果喜欢列表列表,而不是平面列表中的元组列表,那么可以这样做:

    a = range(20) # sample starting list 
    b = [] # new list
    c = [] # alternate new list
    # ny is length of new list. nx length of each list within it
    nx = 5; ny = 4 
    bb = 0; ee = bb + nx # option one: sliding indeces for slices.
    for ii in range(ny-1):
        bb += nx
        ee += nx
        b.append(a[bb:ee])
        c.append(a[slice(ii*nx,nx*(ii+1))]) # option two, use slice()
(我已经尝试过使用列表理解将整个for循环收缩为一行,但没有成功。按照我的使用方法,slice()几乎可以让您达到目的。)
与前面提到的其他方法相比,这些方法的一个可能优势是,如果原始的平面列表不是新的所需列表维度的偶数倍,则不会丢失任何数据。需要注意的是,最后一个列表将比所有其他列表都短,因为它将包含“剩菜”。诚然,这两种方法对我来说都不是很好的方法。

另一种创建列表的方法可以简化为如下所示:

>>>MyList = ['a','b','c','d','e','f']
# Calculate desired row/col
>>>row = 3
>>>col = 2
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)]
>>>NewList
[['a', 'b', 'c'], ['d', 'e', 'f']]
此方法可以扩展为生成任意大小的行和列。如果选择行和列值,使
row*col>len(MyList)
,则包含
MyList
中最后一个值的子列表(row)将在此处结束,
NewList
将简单地用适当数量的空列表填充,以满足行/列规范

>>>MyList = ['a','b','c','d','e','f','g','h']
>>>row = 3
>>>col = 3
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)]
>>>NewList
[['a', 'b', 'c'], ['d', 'e', 'f'], ['g','h']]

>>>row = 4
>>>col = 4
>>>NewList = [MyList[col*i : col*(i+1)] for i in range(row)]
[['a', 'b', 'c', 'd'], ['e', 'f', 'g','h'], [], []]

最好不要使用
list
作为变量名,因为有内置函数
list()
是的,你是对的,我只是快速编辑了代码,我的原始代码看起来不像那样。这个解决方案只有在有足够的项来填充时才有效,否则项目会被切断。创建一个生成器,然后复制对它的引用;聪明。@NickT从技术上讲,它是一个迭代器而不是一个生成器,我不能把它的聪明归功于它:)我知道它是可行的,但这看起来很可怕,很模糊。依靠zip访问iter(l)的两个副本以产生期望的结果是一个好主意吗?生成列表:
map(list,zip(*[iter(l)]*2))
,或者
map(list,zip(*[iter(l)]*3))
,等等。我不明白为什么在第二种方法中使用
slice()
,而不是切片语法。进行计算并不意味着你不能使用a[ii*nx:nx*(ii+1)]或任何东西。我想这应该是公认的答案,因为问题要求的是列表列表,而不是元组列表。或者罗伯特在上述评论中的回答。