使用Python,我试图向后读取列表或字符串。当找到感兴趣的项目时,我想打印从该点到列表末尾的所有项目。我可以做到这一点没有递归,它工作正常,但我觉得有一个更好的方法来做这个递归。 :)
没有递归的示例:
items = ['item1', 'item2', 'item3', 'item4', 'item5']
items_of_interest = []
items.reverse()
for item in items:
items_of_interest.append(item)
if item == 'item3':
break
else:
continue
items_of_interest.reverse()
print items_of_interest
['item3', 'item4', 'item5']
更新
为了增加问题的清晰度,列表实际上是日志文件中一组字符串的grep的输出。字符串集可能重复,我只想要最后一组。
答案 0 :(得分:5)
递归不会使这更简单,它会使它更复杂。
for i, item in enumerate(reversed(items), 1):
if item == 'item3':
items_of_interest = items[-i:]
break
else:
# 'item3' wasn't found
对我来说似乎是最简单有效的方法。您只需将列表从末尾迭代到'item3'
,因为reversed
返回迭代器。
修改:如果您不介意遍历整个列表以创建反转版本,则可以使用:
i = list(reversed(items)).index('item3')
items_of_interest = items[-i-1:]
甚至更简单。如果'item3'
不在列表中,则会引发错误。我使用list(reversed())
代替[:]
,然后reverse()
,因为它是列表上的一次迭代,而不是两次。
编辑2:根据您对其他答案的评论,我的第一个版本可以满足您的需求 - 从最终搜索项目而不会遍历整个列表。问题中的版本必须迭代列表以反转它,就像我的第二个版本一样。
原文的最低限度修改但效率更高的版本是:
items_of_interest = []
for item in reversed(items):
items_of_interest.append(item)
if item == 'item3':
break
items_of_interest.reverse()
答案 1 :(得分:1)
此处不会调用递归解决方案。对于从项目的最后出现到列表末尾查找列表切片的问题,一种方法是定义辅助函数
>>> def rindex(s, x):
... for i, y in enumerate(reversed(s)):
... if x == y:
... return -i-1
... raise ValueError
...
>>> items[rindex(items, "b"):]
['b', 'f']
辅助函数可以被称为rindex
,因为Python有一个rindex
方法来查找字符串中最后一个子字符串。
如果必须以递归方式执行(也许是家庭作业),那么请将其视为此伪代码(尚未完全解决)
def tail_from(list, x):
return tail_from_aux(list, x, [])
def tail_from_aux(list, element, accumulated):
if list is empty:
return []
elif list ends with element
return element::accumulated
else:
last = list[-1]
return tail_from_aux(list[:-1], element, last::accumulated)
但是,这是内存密集型的,遍历整个列表(效率低下),而不是Pythonic。它可能适用于其他语言,但不适用于Python。不要使用。
由于您的实际问题涉及文件和日志文件,因此您可能无法将此问题减少到数组搜索。因此,退房 Read a file in reverse order using python,那里有一些有趣的答案以及一些可供遵循的链接。
如果您能够同意,请考虑将tac
与awk
和grep
混合。