1

我正在尝试编写一个函数来验证列表。

基本上,对于列表中的任何给定元素,它前面的项目或它后面的项目都必须相同。

一个好的列表定义为:

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),下面是我目前拥有的,但它没有返回正确的答案。根据反馈(谢谢!),我更新了它并将参数的名称从 list 更改为 season 并将其设为 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"
4

3 回答 3

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.

于 2013-02-13T20:07:48.937 回答
1

For the more general case of 'comparing element in front and element behind', I would use itertools.tee and itertools.izip -- perhaps gathering the follow pattern into a utility function.

Also, the logic in your loop is inside-out.

# (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

or

return not any(behind != current and current != ahead for behind, current, ahead in itertools.izip(_behind, _current, _ahead))

Note that you'll need to handle 1-length and 2-length lists with a special case.

于 2013-02-13T20:46:25.183 回答
1

要修复您的代码,请使用orand 代替:

if list[i] == list[i-1] or list[i] == list[i+1]:

i-1此外,您应该只在索引和 分别i+1没有“退出”列表时执行这些检查。

到目前为止,这不是性能最好的解决方案,但应该可以工作。

我不会修复你的代码,因为我猜你应该自己想出它。

于 2013-02-13T20:05:16.447 回答