使用Python
我想要以下内容:
[1, 2, 2, 1, 2, 3, 2, 3]
转变为:
[1, 2, 2, [1, 2, 3], 2, 3]
规则:浏览列表中的每个项目。如果我们点击2后跟1创建一个列表并在该列表中包含该1,直到我们达到3,包括该列表,然后关闭列表并继续。这就像1是3是括号。
对于我认为在这种情况下可能需要的递归算法,我不是很好。
一如既往地谢谢。
答案 0 :(得分:3)
仍然记住@Walter对你的问题的评论是正确的,这是你所要求的愚蠢的实现,受到你的问题的最后一点的启发,你建议1
和3
可以替换为[1
和3]
。
>>> import re
>>> s = repr([1, 2, 2, 1, 2, 3, 2, 3])
>>> s = re.sub('1', '[1', s)
>>> s = re.sub('3', '3]', s)
>>> l = eval(s)
>>> l
[[1, 2, 2, [1, 2, 3], 2, 3]]
它的作用是处理列表的表示(字符串)并替换您建议使用正则表达式的方式。最后,它评估字符串(返回列表)。
我把这个实现称为“愚蠢”,因为它可以解决这个问题,但它很丑陋而且非常简单。也就是说,它可以解决问题,所以如果您只是将它用于一次性转换某些数据,那么您需要使用...
HTH!
答案 1 :(得分:2)
def whatever(a):
b = []
tmp = []
last = None
for elem in a:
if tmp:
tmp.append(elem)
if elem == 3:
b.append(tmp)
tmp = []
elif last == 2 and elem == 1:
tmp.append(1)
else:
b.append(elem)
last = elem
return b
print whatever([1, 2, 2, 1, 2, 3, 2, 3])
答案 2 :(得分:1)
这是一个有趣的问题!这是我的解决方案:
def treeize(treeizable, tree=None, stopper=object()):
if tree is None:
tree = []
if treeizable[:1] == [stopper]:
tree.append(treeizable.pop(0))
return tree
elif treeizable[0:2] == [2, 1]:
tree.append(treeizable.pop(0))
subtree = []
treeize(treeizable, subtree, stopper=3)
tree.append(subtree)
return treeize(treeizable, tree, stopper)
elif treeizable:
tree.append(treeizable.pop(0))
return treeize(treeizable, tree, stopper)
else:
return tree
此函数接收应转换为嵌套列表treeizable
的平面列表tree
。 stopper
参数标记当前列表何时完成 - 这是嵌套列表或顶层列表。 (由于stopper
的默认值是object
的实例,因此使用默认值调用列表时不可能存在阻塞,因为object
的实例之间存在不同本身)。
def treeize(treeizable, tree=None, stopper=object()):
为了简化我们的工作,tree
的默认值为None
,如果它具有默认值,则将其设置为列表。这是因为it is problematic to have mutable values as default parameter objects。此外,每次都必须使用空列表键入函数会很烦人。
if tree is None:
tree = []
如果平面列表的第一个值是“阻塞”,则将其添加到树中并返回树。请注意,通过使用treeizable.pop(0)
我实际上从平面列表中删除值。由于仅在定义嵌套列表时设置了止动器,因此,当我们找到它时,不再需要完成:“子树”(即嵌套列表)已完成。另外,请注意我使用列表的切片获取列表的第一个元素。我之所以这样做,是因为输入if treeizable and treeizable[0] == stopper
很无聊。由于切片没有不存在索引的问题,我得到了切片并将其与另一个仅使用塞子的列表进行比较:
if treeizable[:1] == [stopper]:
tree.append(treeizable.pop(0))
return tree
如果列表的开头是“beginner”,那么我从列表中弹出第一个元素,将其附加到树中并创建一个新树 - 即一个空列表。现在我用剩余的列表和空子树调用treeize()
,同时传递3作为停止值。 treeize()
将递归生成一个新树,我将其附加到我的初始树。之后,只需使用列表的剩余部分(不再包含子树的元素)和原始列表调用treeize()
。请注意,塞子应与原始呼叫接收的塞子相同。
elif treeizable[0:2] == [2, 1]:
tree.append(treeizable.pop(0))
subtree = []
treeize(treeizable, subtree, stopper=3)
tree.append(subtree)
return treeize(treeizable, tree, stopper)
如果以前的条件都没有(第一个元素是一个塞子,列表的开头是[2, 1]
)是真的,那么我验证列表中是否有东西。在这种情况下,我弹出第一个元素,添加到树中并使用列表的其余部分调用treeize()
。
elif treeizable:
tree.append(treeizable.pop(0))
return treeize(treeizable, tree, stopper)
如果前一个条件都不成立,那么我们就有一个空列表。这意味着所有元素都放在树中。只需将树返回给用户:
else:
return tree
这似乎有效:
>>> treeize.treeize([1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 3, 2, 4, 5, 3, 3, 2, 3, 4])
[1, 2, 2, [1, 2, 2, [1, 2, 2, [1, 2, 3], 2, 4, 5, 3], 3], 2, 3, 4]
你的问题有尝试的功课。原则上,我们不应该回答它,但它是如此有趣,我无法自助:)如果它是一个功课,但是,不要尝试使用这个解决方案作为你,因为它是错的,你的老师肯定会发现它在Google上:P
答案 3 :(得分:0)
我喜欢状态机:
from itertools import izip, tee
def pairwise(iterable):
a, b = tee(iterable)
next(b)
return izip(a, b)
class Flat(object):
def append_next(self, alist, e0, e1):
alist.append(e0)
if e0 == 2 and e1 == 1:
alist.append([])
self.__class__ = Nested
def append_last(self, alist, e):
alist.append(e)
class Nested(object):
def append_next(self, alist, e0, e1):
alist[-1].append(e0)
if e0 == 3:
self.__class__ = Flat
def append_last(self, alist, e):
alist[-1].append(e)
def nested(flat_list):
if len(flat_list) <= 1:
return list(flat_list)
state = Flat()
nested_list = []
for x, y in pairwise(flat_list):
state.append_next(nested_list, x, y)
state.append_last(nested_list, y)
return nested_list
s = [1, 2, 2, 1, 2, 3, 2, 3]
print nested(s)
给出:
[1, 2, 2, [1, 2, 3], 2, 3]
但这可能更像是pythonic:
def nested(flat_list):
if len(flat_list) <= 1:
return list(flat_list)
pairs = pairwise(flat_list)
nested_list = []
while True:
for x, y in pairs:
nested_list.append(x)
if x == 2 and y == 1:
nested_list.append([])
break
else:
nested_list.append(y)
break
for x, y in pairs:
nested_list[-1].append(x)
if x == 3:
break
else:
nested_list[-1].append(y)
break
return nested_list
答案 4 :(得分:0)
Pease bear with me - 现在是2:50(晚上) - 这是我的版本 - 不是非常美丽,但对我来说效果很好:
def buildNewList(inputList):
last = 0
res = []
for i,c in enumerate(inputList):
if i == 0:
prev = c
if i < last:
continue
if c == 1 and prev == 2:
if 3 in inputList[i:]:
last = i + 1 + inputList[i:].index(3)
res.append(buildNewList(inputList[i: last]))
else:
last = len(inputList)
res.append(buildNewList(inputList[i:len(inputList)]))
else:
res.append(c)
prev = c
return res
l1 = buildNewList([1, 2, 2, 1, 2, 3, 2, 3])
>>> [1, 2, 2, [1, 2, 3], 2, 3]
l2 = buildNewList([1, 2, 2, 1, 2, 3, 2, 1, 2, 3])
>>> [1, 2, 2, [1, 2, 3], 2, [1, 2, 3]]
l3 = buildNewList([1,2,3,1,2,3])
>>> [1, 2, 3, 1, 2, 3]
l4 = buildNewList([1,2,1,1,2,1])
>>> [1, 2, [1, 1, 2, [1]]]