关于python:我的代码不会生成预期的结果

My code doesn't generate the expected result

我希望代码能够打印包含以下数字的列表:

  • 两位数或三位数的乘积
  • 回文
  • 范围[1011011000000]。

最终列表中不应该有5位数字和一些6位数字,因为它们小于101101。但经过处理后仍有一些5位数的数字。为什么会这样?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
list1 = []
for i in range(100, 1000):
    for j in range(100, 1000):
        if str(i*j) == str(i*j)[::-1]:   # checking for palindrome
            list1.append(i*j)


list1 = list(set(list1)) # removing duplicates

print(sorted(list1))
# print(len(list1))

for ii in list1:                      # removing numbers, out of range
    if ii < 101101 or ii >= 1000000:
        list1.remove(ii)


print(sorted(list1))
# print(len(list1))

但是,当我使用集合移除超出范围的元素时,它是有效的。下面给出的代码可以完成这项工作。

1
2
set1 = set(range(10000, 101102))
list1 = list(set(list1) - set1)

但我不明白,为什么以前的代码不能打印出所需的输出?

编辑:正如你们中的一个所建议的,是的,它是这个的一个副本。我不想在现有的银行里查这个问题。


这是一个教科书的例子,说明了为什么你不在适当的地方修改一个列表。罪魁祸首是这个循环:

1
2
3
for ii in list1:                      # removing numbers, out of range
     if ii < 101101 or ii >= 1000000:
          list1.remove(ii)

正如您已经注意到的,list1的初始部分都将是5位数长。按索引列出迭代器。让我们来看一下从5位数列表中删除元素时会发生什么:

  • 从列表开始,ii引用第一个数字:

    1
    2
    3
      10001, 20002, 30003, 40004, ...
        ^
        ii
  • 从列表中删除ii

    1
    2
    3
      20002, 30003, 40004, ...

        ii -> 10001

    ii仍然是一个有效的引用,但不是列表中的项目。列表自然地向后移动了一个元素。

  • 继续循环到下一个元素:

    1
    2
    3
      20002, 30003, 40004, ...
               ^
               ii
  • 希望您能看到它如何跳过您想要过滤掉的相邻元素。

    你有许多可行的解决办法。以下是一些可以让您开始的内容:

  • 使用列表理解创建新列表:

    1
      list1 = [x for x in list1 if len(x) > 5]

  • 完全摆脱有问题的循环,并且只在第一个循环的列表中附加一个字符串(如果该字符串超过了失效时间)。

  • 向后迭代,这样移位不会影响您:

    1
    2
    3
     for ii in reversed(list1):
          if ii < 101101 or ii >= 1000000:
               list1.remove(ii)

    1
    2
    3
     for ii in range(len(list1), -1, -1):
          if list1[ii] < 101101 or list1[ii] >= 1000000:
               del list1[ii]
  • 就我个人而言,我建议选择2,因为这是最简单的选择。您甚至不需要检查字符串的长度,只需要检查数字是否大于99999。


    这是解决问题最简单的方法;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    list1 = []
    for i in range(100, 1000):
         for j in range(100, 1000):
            if str(i*j) == str(i*j)[::-1]:   # checking for palindrome
                list1.append(i*j)

    # Use list comprehension to filter unwanted values from the list.
    list1 = sorted([value for value in set(list1) if 101101 <= value < 1000000])


    print(list1)