Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 确定列表是否为';s的内容从奇数变为偶数_List_Python - Fatal编程技术网

List 确定列表是否为';s的内容从奇数变为偶数

List 确定列表是否为';s的内容从奇数变为偶数,list,python,List,Python,写一些测试用例时,我的思绪飘忽不定,假设有更好的方法来写这样的东西。我有一个列表,它的数字从所有奇数转换为所有偶数,不管在哪里。我需要断言这是事实,以下是我的想法: values = [1, 3, 5, 7, 5, 3, 5, 3, 5, 7, 4, 6, 8, 4, 2, 2, 8, 6] # find all the indexes of odd and even values odds = [i for (i, v) in enumerate(values) if v % 2 == 1]

写一些测试用例时,我的思绪飘忽不定,假设有更好的方法来写这样的东西。我有一个列表,它的数字从所有奇数转换为所有偶数,不管在哪里。我需要断言这是事实,以下是我的想法:

values = [1, 3, 5, 7, 5, 3, 5, 3, 5, 7, 4, 6, 8, 4, 2, 2, 8, 6]

# find all the indexes of odd and even values
odds = [i for (i, v) in enumerate(values) if v % 2 == 1]
evens = [i for (i, v) in enumerate(values) if v % 2 == 0]

# indexes should be a continuous sequence: 0, 1, 2, 3 ... n
assert odds + evens == range(evens[-1] + 1)
看来还有很长的路要走。关于如何减少这种情况的建议

(values[0] % 2) and (len(list(itertools.groupby(values, lambda x: x%2))) == 2)
或者更容易理解的两行:

odds_and_evens = [x%2 for x in values]
assert odds_and_evens.index(0) == odds_and_evens.count(1)
如果
有效,则
赔率和_-evens
将是一些
1
的数字,后面只有
0
,因此如果第一个
0
出现在每个
1
之后,则该值有效

这两种方法都假设需要至少有一个奇数后跟至少一个偶数,我认为OP并没有阐明这一点

如果空列表、所有奇数或所有偶数都应视为有效,则以下方法有效:

odds_and_evens = [x%2 for x in values]
assert odds_and_evens == sorted(odds_and_evens, reverse=True)

嗯,您不需要计算
evens

assert odds == range(len(odds))

一个可能的解决办法是考虑只允许

odd->odd
odd->even
even->even
换句话说,唯一被禁止的过渡是

even->odd
这就意味着

(0, 1) not in ((x%2, y%2) for x, y in zip(values, values[1:]))

只有当
以它自己的所有奇数值开始,然后是它的所有偶数值时,这才是正确的

不必收集指数,您只需基于所有奇数值都位于起点的假设计算过渡点即可;然后检查在该转换点之后是否没有更多的奇数值

断言为真的情况:

values = [1, 3, 5, 7, 5, 3, 5, 3, 5, 7, 4, 6, 8, 4, 2, 2, 8, 6]
odd_count = len([x for x in values if (x % 2)])
assert (not any(x for x in values[odd_count:] if (x % 2) != 0))
断言为假的情况:

values = [1, 3, 5, 7, 5, 3, 5, 3, 44, 5, 7, 4, 6, 8, 4, 2, 2, 8, 6]
odd_count = len([x for x in values if (x % 2)])
assert (not any(x for x in values[odd_count:] if (x % 2) != 0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
value=[1,3,5,7,5,3,5,3,44,5,7,4,6,8,4,2,2,8,6]
奇数计数=len([x代表x,如果(x%2)])
断言(不是任何(如果(x%2)!=0,则值中的x为x[奇数计数:]))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
断言错误

我认为
过滤器
比这里的列表理解更好,例如

filter(isodd, values) + filter(iseven, values) == values

稍长一点,但这似乎涵盖了除需求之外的所有需求(仅偶数、仅奇数、空)。它只需要完整列表上的一个模和一个比较。不像安德鲁的分类答案那样简洁(或聪明),但对于长列表来说更快(?)

values= [1, 3, 5, 7, 5, 3, 5, 3, 5, 7, 2, 4, 6, 8, 10]
evenOdd = [x%2 for x in values]

try:
    evenLoc=evenOdd.index(0)
    assert evenLoc != 0
except ValueError:
    evenLoc=len(evenOdd)

try:
    badActor=evenOdd[evenLoc:].index(1)
    assert False 
except ValueError:
    pass

另一个选项是按奇偶校验对值进行排序,并查看是否有任何更改:

assert sorted(values, key=lambda x: x % 2, reverse=True) == values

受@6502的澄清和解决方案的启发,此生成器方法使用
any()
在测试失败时立即缩短迭代,并且仅在检测到偶数到奇数转换时失败。如果测试通过,最坏情况下的性能是一次完整的迭代:

iter_val = iter(values)
assert not any(next(iter_val)%2 < v%2 for v in values[1:])
iter\u val=iter(值)
不断言任何(下一个(iter_val)%2

从itertools导入izip
不为izip中的i断言任何(i[0]%2
或甚至
断言赔率[-1]==len(赔率)-1
如果您不想比较整个列表。我肯定会进行优化。:)注释中的版本不处理奇数索引列表为空的情况。正确的是
断言不赔率或赔率[-1]==len(赔率)-1
@6502优异分。另外,如果我们需要在原始列表中同时包含赔率和偶数,那么它应该是
断言赔率和赔率[-1]==len(赔率)-1和赔率[-1]!=len(values)-1
。问题作者已经澄清,列表可以全部为奇数或全部为偶数(包括空),并且仍然可以接受(有关此主题的讨论,请参阅我回答中的注释)。您还必须确保发生了
奇数->偶数
。问题中没有说明这一点。。。据我所知,所有奇数或偶数的序列都是有效的(原始代码也接受它)。原始代码也与问题陈述不匹配。“…它的数字从所有奇数值转换为所有偶数值…我需要断言情况就是这样”@Ignacio-IMHO空列表也可以,从所有奇数(无)到所有偶数(再次无)。除此之外,它在哪里并不重要,所以它不必在列表中。这是真的,所有的奇数和偶数都是可以接受的。因为这种转变可以发生在任何地方,所以永远不会发生。创意要点。:)这几乎不是蟒蛇式的;它读起来更像是一个Perl单行程序竞赛提交。是的,对此很抱歉,被v%2==0取代,丑陋但独立。我曾经考虑过这个策略,但从未将其带到任何地方,这也是非常可读的。这个答案很容易理解,我将给出它。但是它两次遍历整个列表,并将奇数和偶数列表连接到另一个列表中,只是为了与原始列表进行比较。我发现dfan和6502的答案更优雅(我也会猜得更快)。dfan的回答还有一个额外的优点,那就是它充分利用了OP最初的思路,只是缩短了思路以节省时间、内存和冗长。@John-我完全同意。这并不快。对我来说,优雅,易于理解和使用。在我看来,我做的几乎和OP完全一样。但是,我没有连接索引,而是连接了项目本身,因此必须与原始列表(而不是范围)进行比较。虽然没有明确列出,但性能绝对是我最不关心的问题。正如约翰所说,这确实符合我的思路,我不能说没有偏见
assert sorted(values, key=lambda x: x % 2, reverse=True) == values
iter_val = iter(values)
assert not any(next(iter_val)%2 < v%2 for v in values[1:])
from itertools import izip
assert not any(i[0]%2 < i[1]%2 for i in izip(vals, vals[1:]))