好吧,我是Python新手,正在学习元组和列表。我被要求创建一个程序,但涉及转换以下列表:
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
进入如下所示的列表:
li = [[(1,2,3),(4,5,6)],[(7,8,9),(10,11,12)],[(13,14,15),(16,17,18)]
基本上,从简单列表到包含子列表的列表,该子列表包含两个包含3个元素的元组。
感谢您的帮助。
感谢。
答案 0 :(得分:2)
解决这个问题的简单方法是分两步完成:首先,将其分解为3元组列表。然后,将其分解为2个列表的列表。
每个步骤有两种方法。
第一种是使用切片和测距:
>>> li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
>>> [li[i:i+3] for i in range(0, len(li), 3)]
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]]
但是我们想要3个元组,而不是3个列表,所以我们需要在表达式周围添加tuple()
:
>>> li_3 = [tuple(li[i:i+3]) for i in range(0, len(li), 3)]
然后,我们再次做同样的事情:
>>> li_23 = [li_3[i:i+2] for i in range(0, len(li_3), 2)]
另一种方法是将相同的迭代器压缩到自身。文档中的itertools
recipes显示了如何执行此操作。事实上,我们只需复制并粘贴配方,然后我们就可以使用它。
>>> from itertools import izip_longest
>>> def grouper(iterable, n, fillvalue=None):
... "Collect data into fixed-length chunks or blocks"
... # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
... args = [iter(iterable)] * n
... return izip_longest(fillvalue=fillvalue, *args)
现在:
>>> li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
>>> grouper(li, 3)
<itertools.zip_longest at 0x10467dc00>
它给了我们一个迭代器;我们必须把它变成一个列表才能看到元素:
>>> list(grouper(li, 3))
[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15], [16, 17, 18]]
所以,现在我们重复同样的步骤:
>>> list(grouper(grouper(li, 3), 2))
[((1, 2, 3), (4, 5, 6)), ((7, 8, 9), (10, 11, 12)), ((13, 14, 15), (16, 17, 18))]
除了我们得到元组的元组,我们想要元组列表,所以:
>>> li_23 = [list(group) for group in grouper(grouper(li, 3), 2)]
在Python中应该只有一种显而易见的方法。那么,它是什么?
more_itertools
第三方包)中为您包装。这些差异中的一个通常对您的用例很重要,在这种情况下,显而易见的方法是执行您想要的操作。对于像这样的简单案例,没有任何重要的事情......无论你发现哪一个更具可读性。
答案 1 :(得分:2)
我个人喜欢这种方法:
>>> li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
>>>
>>> v = iter(li)
>>> li = [(i, next(v), next(v)) for i in v] # creates list of tuples
>>>
>>> v = iter(li)
>>> li = [[i, next(v)] for i in v] # creates list of lists of tuples
>>>
>>> li
[[(1, 2, 3), (4, 5, 6)], [(7, 8, 9), (10, 11, 12)], [(13, 14, 15), (16, 17, 18)]]
顺便说一下,如果元素不适合这样的结构,这将引发错误,例如考虑:
>>> l = [1, 2, 3]
>>> v = iter(l)
>>>
>>> [(i, next(v)) for i in v]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
这可能适合也可能不适合。
如果不是,那么简单的解决方法是给next()
第二个参数:
>>> l = [1, 2, 3]
>>> v = iter(l)
>>>
>>> [(i, next(v, None)) for i in v]
[(1, 2), (3, None)]
<强>参考:强>
答案 2 :(得分:1)
使用zip()
:
>>> [zip(*[iter(sub)]*3) for sub in zip(*[iter(li)]*6)]
[[(1, 2, 3), (4, 5, 6)], [(7, 8, 9), (10, 11, 12)], [(13, 14, 15), (16, 17, 18)]]
答案 3 :(得分:0)
鉴于
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
您可以使用zip(*[iter(li)]*3)
zip(*[iter(li)]*3)
#>>> <zip object at 0x7f0a5578ca28>
并检查:
list(zip(*[iter(li)]*3))
#>>> [(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15), (16, 17, 18)]
然后您可以zip(*[...]*2)
上的zip(*[iter(li)]*3)
:
zip(*[zip(*[iter(li)]*3)]*2)
#>>> <zip object at 0x7f0a5578c998>
并检查:
list(zip(*[zip(*[iter(li)]*3)]*2))
#>>> [((1, 2, 3), (4, 5, 6)), ((7, 8, 9), (10, 11, 12)), ((13, 14, 15), (16, 17, 18))]
内部项目不是列表,因此map
为一个:
map(list, zip(*[zip(*[iter(li)]*3)]*2))
#>>> <map object at 0x7f0a5afd80d0>
并检查:
list(map(list, zip(*[zip(*[iter(li)]*3)]*2)))
#>>> [[(1, 2, 3), (4, 5, 6)], [(7, 8, 9), (10, 11, 12)], [(13, 14, 15), (16, 17, 18)]]