Python: Why Lists do not have a find method?
我试图为这个问题写一个答案,很惊讶地发现列表没有find方法,列表只有index方法(字符串有find和index)。
有人能告诉我这背后的理由吗?为什么弦都有?
- 这个问题是关于这个列表的等价物:"112131".find("1213") => 1ie [1,1,2,1,3,1].find([1,2,1,3]) => 1--如果你想在线性时间内实现这个,你需要自己实现一个字符串匹配算法,这并不容易。
我不知道为什么或者可能埋在某个PEP中,但是我知道2个非常基本的列表"查找"方法,它们是array.index()和in操作符。你总是可以利用这2个来找到你的物品。(同样,重新模块等)
- index方法和in运算符可以在列表中查找单个项(请告诉我是否可以称它们为原子)。OP想知道他是否能找到一个列表是否是另一个列表的子列表,其中的项目以相同的顺序出现。
- 但其背后的基本原理也是通过列表迭代,无论是否嵌套,并使用这些运算符查找它们。OP也可以为此自由开发自己的方法/类/生成器等。
- 数组的标准find方法是搜索单个项。没有人会惊讶地发现数组实现不执行子字符串搜索。
- @格伦·梅纳德:通过python对列表的非常彻底的处理,以及它坚持将字符串与列表进行类似的处理,我确实感到惊讶。
我认为没有单独的"查找"和"索引"方法的理由是它们没有足够的不同。两种方法都会返回相同的结果,如果所需项存在于列表中(这对于两个字符串方法是正确的);如果所需项不在列表/字符串中,则它们会有所不同;但是,您可以轻松地从另一种方法构建find/index中的任何一种。如果您来自其他语言,那么对于您可以轻松测试的非错误条件,引发和捕获异常似乎是不礼貌的做法,但是在Python中,通常认为先拍摄然后再问问题更像是Python式的,呃,使用异常处理而不是像这样的测试(例如:更好地"尝试"一些东西并捕获异常或测试,如果可能的话,首先要避免异常?).
我不认为把"find"建立在"index"和"in"之外是个好主意,比如
1 2 3 4
| if foo in my_list:
foo_index = my_list.index(foo)
else:
foo_index = -1 # or do whatever else you want |
因为in和index都需要一个o(n)传递列表。
最好从"index"中构建"find"并尝试/catch,例如:
1 2 3 4
| try:
foo_index = my_list.index(foo)
catch ValueError:
foo_index = -1 # or do whatever else you want |
现在,关于为什么列表是这样构建的(只有索引),而字符串是以另一种方式构建的(有单独的索引和查找)。我说不上来。
列表的"查找"方法是index。
我认为string.find和list.index之间的不一致是很不幸的,无论是在名义上还是行为上:string.find在没有找到匹配时返回-1,而list.index会导致值错误。这本可以设计得更加一致。这些操作之间唯一不可调和的区别是,string.find搜索一个项目字符串,其中list.index只搜索一个项目(仅此一项,不能证明使用不同的名称是正确的)。
- 下次在回复中尝试使用"asdfasdf".index('z')。
- @aaronmcsmound:它强调了经常重复的"做某件事的一个显而易见的方法"的荒谬性,当他们甚至不能坚持核心字符串方法时。
- 但我的例子的要点是,他们确实坚持这一点。list和string都有一个行为完全相同的index方法。只是string在上面加了一个find方法。我不知道他们为什么不为list做这个,但是list.index和string.find之间没有等价物。
- @aaronmc平滑:不一致性只是稍微改变了一点,其根本原因是冗余的搜索函数。(getattr处理得很好,根据需要,既允许哨兵也允许例外。)
- @aaronmcsmound,虽然string和list都有一个.index()方法,但它做的并不完全相同。对于字符串,它将找到子字符串,但列表的子列表——对我来说,这是不一致的另一个例子。
- @马里诺,这是一个很好的观点。我想我错了。不是第一次跑一英里
- @阿隆姆斯朗克。在我点击"添加评论"按钮之前,你怎么能看到并回复我的评论?这真的让我不爽,现在我无法修正里面的打字错误。