有没有一种pythonic方法来检查列表元素,并在列表末尾停止(没有错误)?
Posted
技术标签:
【中文标题】有没有一种pythonic方法来检查列表元素,并在列表末尾停止(没有错误)?【英文标题】:Is there a pythonic way to check list elements, and stop at end of list (without an error)? 【发布时间】:2016-08-25 04:28:00 【问题描述】:我有一个复杂的系统后端,但我试着做一个简单的例子,所以你知道我在说什么。
基本上我有一个 ID 列表,用户(通过 gui)将在这个列表中循环生成 ID。
在某些时候,他们想要检查并修复所有他们搞砸或跳过的问题(这些都将具有相同的 ID);这就是我有问题的地方。
我已经写了一些可以做到这一点的东西(检查列表是否有错误的 ID),但问题是一旦它到达列表的末尾,就会引发索引错误。我想干净地退出while循环,而是退出函数
def nextID():
'''
increment counter until we find a junk ID
'''
global tindx
skips = 0
while IDs[tindx] != 'junk_id' and tindx != len(IDs):
print 'This ID is good: %s' %IDs[tindx]
skips+=1
tindx+=1
print 'Skipped %i IDs' %(skips), 'tindx is now',tindx
这被设计成(又是一个巨大的简化)以下列方式使用
tindx = 0
IDs = ['abc','bcd','cde','junk_id','junk_id','def','efg','junk_id','fgh','ghi']
# This is all hadled with in an interactive GUI
# User wants next ID
nextID()
# User changes ID
IDs[tindx] = 'good_id!'
# User wants next ID
nextID()
# User changes ID
IDs[tindx] = 'another_good_id'
# etc ....
我知道如果我切换while循环条件的顺序,它将避免自动IndexError
,但用户不会知道他们已经到达列表的末尾并会尝试更改ID(得到同样的错误)。
我想告诉用户他们完成了运行save_IDs()
函数,然后退出程序。这边重新设计软件,有没有比加入下面if
条件更好的办法
while ...
if tindx == len(IDs):
print 'you\'re done'
save_IDs()
return None
【问题讨论】:
【参考方案1】:正如您所提到的,您确实需要在 while 上切换参数:
while tindx != len(IDs) and IDs[tindx] != 'junk_id':
...
否则它会先尝试访问IDs[tindx],然后检查是否无效。
对于这个问题,您可以让 nextID 在到达末尾时返回新索引或 None:
def nextID(last_offset):
offset = last_offset
while offset < len(IDs) and IDs[offset] != 'junk_id'
offset += 1
if offset >= len(IDs):
return None
if offset > last_offset:
print("Skipped %d IDs" % (offset - last_offset))
return offset
然后使用它:
current_offset = 0
while doing things:
current_offset = nextID(current_offset)
if current_offset == None:
# All done.
break
print("New offset: %d" % (offset))
if user changes id:
IDs[current_offset] = 'good_id!'
else:
# If the user didn't change the ID for whatever reason,
# you'll need to manually increment current_offset.
current_offset += 1
print("All done, saving..")
saveIDs()
如果您在 GUI 内的回调中,那么您可能会有更多类似这样的内容:
def userChangedID(new_value):
global current_offset
IDs[current_offset] = new_value
current_offset = nextID(current_offset)
if current_offset == None:
finish()
def userSkippedID():
global current_offset
current_offset = nextID(current_offset + 1)
if current_offset == None:
finish()
def finish():
global finished
finished = True
print("All done, saving...")
saveIDs()
理想情况下,一个方法应该具有尽可能少的副作用,因为它需要做它应该做的事情。
在原始代码中,nextID() 不仅是“寻找下一个 ID”,它还改变了整个进程的状态。
从开发人员的角度来看,这会造成相当大的误导,他们可能只是希望 nextID() 找到并返回下一个 ID。
【讨论】:
感谢您关于我对 nextID 的定义的观点。由于主要是自学成才,这是我遇到的一个常见问题。你给出的例子读起来好多了,我想我会重组我用来模拟这个的函数。这将是一些工作,但我以后可能会为此感谢自己。感谢您为我展示这一点。以上是关于有没有一种pythonic方法来检查列表元素,并在列表末尾停止(没有错误)?的主要内容,如果未能解决你的问题,请参考以下文章
Python:检查列表中至少一个正则表达式是不是与字符串匹配的优雅方法