23

人们可能想做与扁平化列表相反的事情,就像这里:我想知道如何将扁平列表转换为列表列表。

在 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']]

有没有更“pythonic”的方式来做到这一点?

4

4 回答 4

39
>>> 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 的解决方案

如何zip(*[iter(s)]*n)工作

于 2012-04-12T13:40:16.823 回答
13

这通常使用itertools文档中的石斑鱼配方完成:

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.izip_longest(fillvalue=fillvalue, *args)

例子:

>>> my_list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> list(grouper(2, my_list))
[('a', 'b'), ('c', 'd'), ('e', 'f'), ('g', None)]
于 2012-04-12T13:41:32.237 回答
10

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

>>>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将在那里结束,并且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'], [], []]
于 2015-04-29T03:48:01.877 回答
0

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

    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() 几乎可以让你到达那里。)这些方法的一个可能优势是其他提到的是,如果您的原始平面列表不是您的新的所需列表列表的维度的偶数倍,您将不会丢失任何数据。需要注意的是,最后一个列表将比所有其他列表短,因为它将包含“剩菜”。当然,这些方法都没有让我觉得非常pythonic。

于 2015-03-18T06:10:04.347 回答