【发布时间】:2012-08-03 02:47:55
【问题描述】:
我的清单是:
mylist=[1,2,3,4,5,6]
我想将 mylist 转换为对列表:
[[1,2],[3,4],[5,6]]
有这样做的pythonic方式吗?列表理解?迭代工具?
【问题讨论】:
标签: python list itertools list-comprehension
我的清单是:
mylist=[1,2,3,4,5,6]
我想将 mylist 转换为对列表:
[[1,2],[3,4],[5,6]]
有这样做的pythonic方式吗?列表理解?迭代工具?
【问题讨论】:
标签: python list itertools list-comprehension
是的,列表理解是我通常的做法:
>>> 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)]
无论如何,我通常使用生成器而不是列表,因此通常不需要第 2 行。
【讨论】:
zip(*[mylist]*groupsize) 以允许通用组大小。当然,zip 方式在处理长度不能被所需组大小整除的列表时总是会遇到问题。
另一种方式:
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 documentation中的“石斑鱼”食谱:
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)
【讨论】:
grouper。
[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 的建议。
现在完全不同:这是一个解决方案 (ab),使用 zip 和一个临时函数而不是中间赋值:
>>> (lambda i: zip(i, i))(iter(mylist))
[(1, 2), (3, 4), (5, 6)]
【讨论】:
xrange 步进 2,大部分数学运算就消失了。