我的列表是:
mylist=[1,2,3,4,5,6]
我想把mylist转换成一对一对的列表:
[[1,2],[3,4],[5,6]]
有没有一种pythonic的方法来做到这一点?列表推导?itertools?
我的列表是:
mylist=[1,2,3,4,5,6]
我想把mylist转换成一对一对的列表:
[[1,2],[3,4],[5,6]]
没错,列表推导式是我通常的做法:
>>> groupsize = 2
>>> [mylist[x:x+groupsize] for x in range(0,len(mylist),groupsize)]
[[1,2],[3,4],[5,6]]
>>> groupsize = 3
>>> [mylist[x:x+groupsize] for x in range(0,len(mylist),groupsize)]
[[1,2,3],[4,5,6]]
我使用range
来确保可移植性,如果你正在使用Python 2(很可能是),请将range
更改为xrange
以节省内存。
我偏爱的技术:
>>> mylist = [1, 2, 3, 4, 5, 6]
>>> mylist = iter(mylist)
>>> zip(mylist, mylist)
[(1, 2), (3, 4), (5, 6)]
我通常使用生成器而非列表,因此第二行通常不需要。
另一种方法:
zip( mylist[:-1:2], mylist[1::2] )
这将产生一个元组列表:
>>> zip(mylist[:-1:2],mylist[1::2])
[(1, 2), (3, 4), (5, 6)]
如果你真的想要一个列表的列表:
map(list, zip(mylist[:-1:2],mylist[1::2]))
请查看itertools文档中的“grouper”配方:
def grouper(n, iterable, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
[mylist[2*n:2*n+2] for n in xrange(len(mylist)/2)]
这个解决方案结合使用列表推导和切片来从原始列表中提取成对的序列,并构建一个切片列表。
或者,[mylist[n:n+2] for n in xrange(0, len(mylist), 2)]
是相同的,除了xrange
以两个为单位计数而不是切片。感谢Steven Rumbalski的建议。
现在,有一种不同的解决方案:这里是一种利用zip
和临时函数而不是中间赋值的方法:
>>> (lambda i: zip(i, i))(iter(mylist))
[(1, 2), (3, 4), (5, 6)]
xrange
按2步增加,大部分数学问题就会消失。 - Steven Rumbalski
zip(* [mylist] * groupsize)
以允许通用组大小。当然,使用zip的方法始终会在处理长度不能被所需组大小整除的列表时出现问题。 - Josiah