我正在尝试编写一个函数来验证列表。
基本上,对于列表中的任何给定元素,其前面的项目或其后面的项目必须相同。
好的清单定义为:
good_list = ["H", "H", "H", "M", "M", "L", "L", "M", "M", "H", "H", "H"]
错误列表定义为:
bad_list = ["H", "M", "H", "M", "M", "L", "L", "M", "M", "H", "H", "H"]
我花了几天时间尝试不同的解决方案(并在stackoverflow上阅读)以下是我目前所拥有的,但它没有返回正确的答案。根据反馈(谢谢!),我已更新它并将参数名称从列表更改为季节并使其成为OR。它仍然会返回一个“有效列表”但不应该?
bad_list = ["H", "M", "H", "M", "M", "L", "L", "M", "M", "H", "H", "H"]
def check_list(season):
for i, a in enumerate(season):
if season[i] == season[i-1] or season[i] == season[i+1]:
return True
return False
result = check_list(bad_list)
if result == True:
print "Valid list"
else:
print "Invalid list"
答案 0 :(得分:4)
我只是使用itertools.groupby
:
if all(len(tuple(group)) > 1 for key, group in itertools.groupby(the_list)):
print "valid"
else:
print "invalid"
基本上,请求“每个元素在其之前或之后应该具有相等的元素”等同于“列表必须由最小长度为2的连续元素组成”。 groupby
函数会生成这些组,您只需检查all
它们的长度是否大于1
。
答案 1 :(得分:1)
要修复代码,请使用or
代替和:
if list[i] == list[i-1] or list[i] == list[i+1]:
此外,如果索引i-1
和i+1
没有“脱离”列表,您应该只执行这些检查。
到目前为止,这不是表现最佳的解决方案,但应该有效。
我不会修改你的代码,因为我猜你应该自己想出它。
答案 2 :(得分:1)
对于'比较前面的元素和后面的元素'的更一般情况,我会使用itertools.tee
和itertools.izip
- 也许将跟随模式收集到效用函数中。
此外,循环中的逻辑是由内而外的。
# (inside the function)
_behind, _current, _ahead = itertools.tee(the_list, 3)
# should error check as well
_current.next()
_ahead.next()
_ahead.next()
for behind, current, ahead in itertools.izip(_behind, _current, _ahead):
# fixing logic here
if behind != current and current != ahead:
return False
return True
或
return not any(behind != current and current != ahead for behind, current, ahead in itertools.izip(_behind, _current, _ahead))
请注意,您需要使用特殊情况处理1长度和2长度列表。