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]]
如何修复代码才能实现此目的?
答案 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)]