无法让 != 处理迭代器变量

Can't get != to work on iterator variable

提问人:P T 提问时间:11/9/2023 最后编辑:XMehdi01P T 更新时间:11/9/2023 访问量:106

问:

我的问题出在比较运算符“ if combination[0] != b ”中。我希望“组合”变量的第一位数字不等于“badnumbers”列表中的数字(因此没有以 0,5 和 6 开头的组合),但由于某种原因,该代码被忽略,如运行程序时所示。但是,如果我将比较运算符从 != 更改为 ==,则程序运行良好(因为仅打印以 0,5 和 6 开头的组合)。

我的代码:

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
totalcombinations = []
for i in numbers:
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            for b in badnumbers:
                if combination[0] != b and combination not in totalcombinations:
                    totalcombinations.append(combination)
                    
for c in totalcombinations:
  print(c)

起初我尝试使用“if combination[0] != b ”,然后使用“if str(combination[0]) != b”并使用 ChatGPT 获得一些答案,但没有任何效果。我预计不会打印任何以 0、5 和 6 开头的组合。

python list for-loop if-statement

评论

2赞 Tim Roberts 11/9/2023
将 / 作为循环中的第一个语句会更聪明。此外,您可以进行并避免“已包含”测试。if i in badnumbers:continuefor itotalcombinationsset
2赞 Tim Roberts 11/9/2023
此外,/ / 将在 1 个循环而不是 4 个循环中完成所有这些操作。for n in range(1000):if n < 100 or n in range(500,700):continue
3赞 juanpa.arrivillaga 11/9/2023
撇开效率低下不谈,想想看,你正在循环.假设是 .在 的第一次迭代中,条件为 false,并且它不执行任何操作。在下一次迭代中,是 ,因此它将被追加badnumberscombinations000badnumbersifb'5'
0赞 Mark Tolonen 11/9/2023
另请查看 itertools.product。 会给你同样的答案。totalcombinations = list(itertools.product('1234789',range(10),range(10)))

答:

0赞 Nijat Mursali 11/9/2023 #1

我们有一个包含从“0”到“9”的所有数字的列表编号,以及一个包含数字“0”、“5”和“6”的坏数字列表。我们从一个空的 totalcombinations 列表开始,以存储有效的组合。我们使用循环来遍历列表中的元素。对于每个元素,它代表组合的第一位数字,我们使用条件检查是否不在坏数字列表中。fornumbersiiif i not in badnumbers

如果列出,我们继续生成组合。我们使用两个嵌套的 for 循环来分别为第二位和第三位数字 w 和 l 生成所有可能的组合。i is not in the badnumbers

我们通过连接三位数字(i、w 和 l)来创建组合,并将其添加到总组合列表中。

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
totalcombinations = []

for i in numbers:
    if i not in badnumbers:
        for w in numbers:
            for l in numbers:
                combination = i + w + l
                totalcombinations.append(combination)

for c in totalcombinations:
    print(c)

一个衬里是这样的:

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']

# Generate all combinations and filter out the bad ones
totalcombinations = [i + w + l for i in numbers for w in numbers for l in numbers if i not in badnumbers]

for c in totalcombinations:
    print(c)

评论

0赞 Nijat Mursali 11/9/2023
@juanpa.arrivillaga 是的,我的错,现在应该解决了。
0赞 Nijat Mursali 11/9/2023
现在两个版本都应该很好。
0赞 Nijat Mursali 11/9/2023
@juanpa.arrivillaga 希望现在已经足够了!
1赞 NoDakker 11/9/2023 #2

如好注释中所述,任何串联字符串的测试都将通过其中一个错误数字的“!=”测试,并随后将该字符串附加到总组合列表中。

这样一来,您可能只想简化测试条件,使其不包括串联字符串,除非第一个字符/数字不在错误数字列表中。以下是您的研究的重构版本。

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
totalcombinations = []
for i in numbers:
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            # Simplified test
            if combination[0] not in badnumbers and combination not in totalcombinations:
                totalcombinations.append(combination)

for c in totalcombinations:
    print(c)

以下是终端上的一些示例输出,表示跳过以任何错误数字开头的字符串。

craig@Vera:~/Python_Programs/BadNumbers$ python3 BadNumbers.py 
100
101
102
103

496
497
498
499
700
701
702
703
704

试一试。

0赞 XMehdi01 11/9/2023 #3

避免以错误数字中的数字开头的组合。您可以使用 作为循环中的第一个语句。if i in badnumbers: continue

以下是更正后的代码:

numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
badnumbers = {"0", "5", "6"}  
totalcombinations = set()
for i in numbers:
    if i in badnumbers:
        continue
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            totalcombinations.add(combination)
for c in totalcombinations:
    print(c)

我的代码生成三位数组合,不包括以 0、5 或 6 开头的组合。

0赞 Jasmijn 11/9/2023 #4

归根结底,问题在于逻辑问题。“for any in”的反义词不是“for any in”,而是“for all in”。i == bbbadnumbersi != bbbadnumbersi != bbbadnumbers

你可以为此使用 - ( 真的应该被命名为这样的东西,以明确它的作用)。forelseelsenobreak

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
totalcombinations = []
for i in numbers:
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            for b in badnumbers:
                if i != b and combination not in totalcombinations:
                    break
            else:
                totalcombinations.append(combination)
                    
for c in totalcombinations:
  print(c)

现在这里有一个严重的低效率:你正在检查一大堆你不需要的东西。

例如,每 100 个内部循环仅更改一次,因此无需检查此项。i

并且永远不会在,因为每个数字都是唯一的。combinationtotalcombinations

我们也不需要显式循环,我们可以在这里使用:badnumbersin

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
totalcombinations = []

for i in numbers:
    if i in badnumbers:
        continue # just go to the next i
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            totalcombinations.append(combination)
                    
for c in totalcombinations:
  print(c)

现在,您还可以进一步改进这一点,因为您事先知道您不想从哪些数字开始:(如果您想多次运行该循环,则特别有用。

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
startnumbers = [num in numbers if num not in badnumbers]
totalcombinations = []

for i in startnumbers:
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            totalcombinations.append(combination)
                    
for c in totalcombinations:
  print(c)

当然,也可以为您提供帮助:itertools

from itertools import product

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
startnumbers = [num in numbers if num not in badnumbers]
totalcombinations = list(f'{i}{w}{l}' for i, w, l in product(startnumbers, numbers, numbers))

评论

0赞 Jasmijn 11/9/2023
我在第一段中提到的逻辑是德摩根定律的应用,在 Python 中可以表示为 和not (a or b) == not a and not bnot (a and b) == not a or not b
1赞 Artem 11/9/2023 #5

该问题与循环有关。例如,对于组合 000,此循环正在执行的操作:for b in badnumbers:

  1. 它将 000 的第一个数字进行比较,因此 0 与列表的第一项进行比较。此列表的第一个数字是 0,因此该组合不会像您预期的那样添加到 中。badnumberstotalcombinations
  2. 但是,它将 0 与 的第二项 、 与 5 进行比较。5 不等于 0 并且这个组合不在 中,因此它将被添加到 的列表中。badnumberstotalcombinationstotalcombinations
  3. 在上一次迭代中也做了同样的事情,但该组合已经在 的列表中。totalcombinations

不需要更改那么多代码的最简单解决方案之一是

numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
badnumbers = ['0', '5', '6']
totalcombinations = []
for i in numbers:
    for w in numbers:
        for l in numbers:
            combination = i + w + l
            if not (combination[0] in badnumbers) and combination not in totalcombinations:
                totalcombinations.append(combination)
                    
for c in totalcombinations:
  print(c)

该循环被删除,而是用于检查第一个数字是否存在于 的列表中,尽管可以用更少的行数重写代码。for b in badnumbersif not (combination[0] in badnumbers)badnumbers