【问题标题】:For loop inside for loop causing fails after second loopfor 循环内的 for 循环导致第二个循环后失败
【发布时间】:2016-03-24 15:28:39
【问题描述】:

大家晚上好,

我正在编写一个检查磁盘地址以查看是否存在磁盘的代码。我通过执行一次扫描来验证它是哪个磁盘号,禁用磁盘,再次扫描,然后比较结果以确定磁盘,然后在循环重复扫描下一个地址之前重新启用磁盘。正如您在下面的输出中看到的那样,它通过了该过程,为插槽 1 获取了 scan1 和 scan2,我打印出来以显示磁盘 0 已被移除,因此它必须是插槽中的磁盘。循环重复下一个插槽并获取 scan1 和 scan2 以显示删除后,disk1 已消失,这意味着它在该插槽中。

但是,当我在内部执行第二个 for 循环以比较两个字符串并将差异实际保存到变量时,变量结果的输出只是一个空白字符串“”。因为它只是一个空白字符串,所以我得到了字符串索引超出范围的错误消息,这是有道理的。我只是不明白主 for 循环中的第二个 for 循环如何适用于一个循环,但是当第二次比较 scan1 和 scan2 时(即使我可以看到它们不同)它只是存储一个空白字符串到结果。

# Addresses of each populated slot
Slot1PackedAddress = '+-01.0-[82]----00.0'
Slot2PackedAddress = '+-03.0-[84]----00.0'
Slot3PackedAddress = '+-03.0-[08]----00.0'
Slot4PackedAddress = '+-01.0-[01]----00.0'
Addresses = [Slot1PackedAddress, Slot2PackedAddress, Slot3PackedAddress, Slot4PackedAddress]

InitialChecks = [None]*5
diskchange = [0]*5
Slot = [None]*5

SlotOn = ['4/1/', '5/1/', '6/1/', '7/1']
SlotOff = ['4/0/', '5/0/', '6/0/', '7/0']

for i in range(1,3):

    InitialChecks[i] = ['Slot%i = 1' %i]
    InitialChecks[i] = str(InitialChecks[i]).replace('[\'', '').replace('\']', '')

    with open('lspci.sh', 'rb') as file:
        script = file.read()
    subprocess.call(script, shell=True)

    if Addresses[i-1] in open('results').read():
        result = ' '

        print("Device in Slot %d, checking to see what drive number it is..." %i)

        scan1 = ''
        # Initial disk scan
        os.system("sudo parted -l > scan1.txt")
        with open('scan1.txt', 'rb') as file:
            for line in file:
                for part in line.split():
                    if "nvme" in part:
                        scan1 = scan1 + part
        print scan1

        # Disable the slot to get ready to record which drive number disappeared
        with open('removeslot%d.sh' %i, 'rb') as file:
            script = file.read()
        subprocess.call(script, shell=True)

        scan2 = ''
        # Initial disk scan
        os.system("sudo parted -l > scan2.txt")
        with open('scan2.txt', 'rb') as file:
            for line in file:
                for part in line.split():
                    if "nvme" in part:
                        scan2 = scan2 + part
        print scan2

        for nvme in scan1:
            if nvme not in scan2:
                    result = result + nvme 


        print("result is " + result)

        disk = filter(str.isdigit, result)
        strdiskchange = str(disk)
        diskchange[i] = int(strdiskchange[0])
        print diskchange[1]
        print("The new disk added to slot %i is /dev/nvme%dn1" %(i, diskchange[i]))

        # Rescan to re-enable the drive that was disabled.
        with open('rescan.sh', 'rb') as file:
            script = file.read()
        subprocess.call(script, shell=True)

        # Represents that Slot 1 is populated and on
        Slot[i] = 1

这是错误输出:

Device in Slot 1, checking to see what drive number it is...
/dev/nvme0n1:/dev/nvme1n1:
/dev/nvme1n1:
drive that disappear is 0
The new disk added to slot 1 is /dev/nvme0n1
Device in Slot 2, checking to see what drive number it is...
/dev/nvme0n1:/dev/nvme1n1:
/dev/nvme0n1:
drive that disappear is 
Traceback (most recent call last):
  File "GUIArduino.py", line 75, in <module>
    diskchange[i] = int(strdiskchange[0])
IndexError: string index out of range
pciedev3ubuntu@PCIeDev3ubuntu:~/Documents$ 

感谢大家的帮助

【问题讨论】:

  • 查看drive that disappear is ... 你有一个空字符串,所以strdiskchange[0] 是一个超出范围的索引
  • 我发帖说我知道这一点,这就是我收到错误消息的原因。但是,通过字符串的第一个循环不是空的,正如你所看到的,我比较差异的两个字符串是不同的,所以据我所知它不应该是空的,所以这就是我的问题试图解决,而不是错误消息本身。
  • 这个for nvme in scan1 迭代scan1 字符串中的单个字符。我很困惑你期望 result 变量变成什么。
  • 我认为您的scan1scan2 应该是列表或集合,而不是字符串。
  • @PM2Ring,我相信我曾经尝试过一个列表,并收到了类似的结果。有什么具体的我应该将列表/集合中的变量设置为?因为当我这样做时,我只是做了 scan = ['']*3.

标签: python loops for-loop nested


【解决方案1】:

您可以使用tryCatch 函数忽略循环中的错误(例如空白或空单元格/向量)并从中断处继续

http://mazamascience.com/WorkingWithData/?p=912

【讨论】:

    【解决方案2】:

    我想通了。我回去使用正在工作的 lsblk 代码,但只是添加了 'and 'p' not in line' 部分以跳过任何有 p 的行,因为只有分区行包含 p。

        lsblk = subprocess.Popen(['lsblk'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        scan2 = [line.strip() for line in lsblk.stdout if 'nvme' in line and 'p' not in line]
    

    刚刚替换了

        os.system("sudo parted -l > scan1.txt")
        with open('scan1.txt', 'rb') as file:
            for line in file:
                for part in line.split():
                    if "nvme" in part:
                        scan1 = scan1 + part
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-29
      • 2022-06-13
      • 2013-08-04
      • 2020-07-30
      • 1970-01-01
      • 2021-10-28
      • 2015-03-21
      • 1970-01-01
      相关资源
      最近更新 更多