【问题标题】:python loop to find the largest integer from a listpython循环从列表中找到最大的整数
【发布时间】:2017-02-28 14:31:19
【问题描述】:

我编写了一个脚本来下拉 aws 标签列表,然后读取最后一个八位字节并告诉我哪个是最高 IP。例如。这是返回的标签列表:

['vlslabmc, 172.16.0.13/24', 'vlslabmc,172.16.0.5/24', 'vlslabmc,172.16.0.3/24', 'vlslabmc,172.16.0.12/24', 'vlslabmc,172.16.0.16/24', 'vlslabmc,172.16.0.6/24', 'vlslabmc,172.16.0.1/24', 'vlslabmc,172.16.0.11/24', 'vlslabmc,172.16.0.15/24', 'vlslabmc,172.16.0.17/24', 'vlslabmc,172.16.0.4/24', 'vlslabmc,172.16.0.7/24', 'vlslabmc,172.16.0.10/24', 'vlslabmc,172.16.0.9/24', 'vlslabmc,172.16.0.8/24', 'vlslabmc,172.16.0.2/24', 'vlslabmc,172.16.0.14/24']

这是我从 tagLis 中锻炼最大 IP 的代码(注意最大的是 17, 172.16.0.17)

 21 def findLargestIP():
 22         for i in tagList:
 23                 #remove all the spacing in the tags
 24                 ec2Tags = i.strip()
 25                 #seperate any multiple tags
 26                 ec2SingleTag = ec2Tags.split(',')
 27                 #find the last octect of the ip address
 28                 fullIPTag = ec2SingleTag[1].split('.')
 29                 #remove the CIDR from ip to get the last octect
 30                 lastIPsTag = fullIPTag[3].split('/')
 31                 lastOctect = lastIPsTag[0]
 32                 ipList.append(lastOctect)
 33                 largestIP  = int(ipList[0])
 34                 for latestIP in ipList:
 35                         if int(latestIP) > largestIP:
 36                                 largestIP = latestIP
 37         return largestIP

我不知道为什么.. 但是当我打印最大 IP 的值时,它总是打印出 16。我已经完成了它应该工作的代码 (我避免使用 max 函数,因为我是只是学习编码)

非常感谢任何帮助。

谢谢

编辑下面的答案和一个问题

好的,多亏了 cmarie 的提示,我得到了它的工作,问题主要是

33                 largestIP  = int(ipList[0])

这是之前运行的代码,在列表 append 中添加了打印语句:

'13']
['13', '5']
['13', '5', '3']
['13', '5', '3', '12']
['13', '5', '3', '12', '16']
16
['13', '5', '3', '12', '16', '6']
16
['13', '5', '3', '12', '16', '6', '1']
16
['13', '5', '3', '12', '16', '6', '1', '11']
16
... ...
['13', '5', '3', '12', '16', '6', '1', '11', '15', '17', '4', '7', '10', '9', '8', '2']
    16
['13', '5', '3', '12', '16', '6', '1', '11', '15', '17', '4', '7', '10', '9', '8', '2', '14']
16

基本上发生的事情是在这个循环中:

33                 largestIP  = int(ipList[0])
 34                 for latestIP in ipList:
 35                         if int(latestIP) > largestIP:
 36                                 largestIP = latestIP

循环在第一个最大的整数处停止。在这种情况下是 16。*我不知道为什么会这样,但确实如此

这是工作代码:

19 def findLargestIP():
 20         ipList =[]
 21         for i in tagList:
 22                 #remove all the spacing in the tags
 23                 ec2Tags = i.strip()
 24                 #seperate any multiple tags
 25                 ec2SingleTag = ec2Tags.split(',')
 26                 #find the last octect of the ip address
 27                 fullIPTag = ec2SingleTag[1].split('.')
 28                 #remove the CIDR from ip to get the last octect
 29                 lastIPsTag = fullIPTag[3].split('/')
 30                 lastOctect = lastIPsTag[0]
 31                 ipList.append(int(lastOctect))
 32                 print ipList
 33                 largestIP  = 0
 34                 for latestIP in ipList:
 35                         if latestIP > largestIP:
 36                                 largestIP = latestIP
 37                                 print latestIP
 38         print largestIP
 39         return largestIP

结果:

[13, 5, 3, 12, 16]
13
16
[13, 5, 3, 12, 16, 6]
13
16
[13, 5, 3, 12, 16, 6, 1]
13
16
[13, 5, 3, 12, 16, 6, 1, 11]
13
16
[13, 5, 3, 12, 16, 6, 1, 11, 15]
13
16
[13, 5, 3, 12, 16, 6, 1, 11, 15, 17]
13
16
17

注意它找到了 17。

【问题讨论】:

    标签: python list loops integer


    【解决方案1】:

    所以我不得不稍微重构你的代码。我假设 ipList 是一个空列表。你确定你测试过它是否真的运行了吗?特别是你的 if 语句

    if int(latestIP) > largestIP:
        largestIP = latestIP
    

    会返回一个

    TypeError: unorderable types: int() > str()
    

    因为您会将字符串分配给最大IP,然后在下一次迭代中,您会将字符串与int 进行比较。除此之外,您的代码似乎可以正常工作。它返回 17 作为对我来说最大的最后一个八位字节,这似乎是正确的。

    如果您的意图是返回 ip 地址列表中最大的最后一个八位位组,您可能需要稍微不同的处理方式。

    选项1:先累积IP地址列表

    不用在循环中嵌套一个 for 循环来遍历所有标签,您可以先累积标签,然后遍历并找到最大值。这样,您只需遍历一次标签列表,然后遍历一次 ip 列表,而不是每次遍历标签列表时都遍历整个 ip 列表。

    选项 2:创建仅包含最后一个八位字节的列表

    与选项 1 类似,您将遍历您的 tagList 并将所有转换为整数的 IP 地址的最后八位字节累积到一个列表中,而不是整个 IP 地址。在之后的循环中,您可以使用八位字节调用列表中的 max(我猜您想避免这种情况)。

    选项 3:拥有最大的价值

    我认为这是最好的解决方案。当您浏览标签列表时,您可以保留一个变量,该变量将具有迄今为止最大的最后一个八位位组。这样你只需要遍历标签列表一次,仍然会得到迄今为止最大的最后一个八位位组。

    如果您想获取整个 IP 地址,选项 1 和 3 仍然有效,但对于选项 2,您可能需要查看 python dictionaries

    【讨论】:

      【解决方案2】:

      为什么要这么复杂。这是一个用于此的衬线

      ip_list = ['vlslabmc, 172.16.0.13/24', 'vlslabmc,172.16.0.5/24', 'vlslabmc,172.16.0.3/24', 'vlslabmc,172.16.0.12/24', 'vlslabmc,172.16.0.16/24', 'vlslabmc,172.16.0.6/24', 'vlslabmc,172.16.0.1/24', 'vlslabmc,172.16.0.11/24', 'vlslabmc,172.16.0.15/24', 'vlslabmc,172.16.0.17/24', 'vlslabmc,172.16.0.4/24', 'vlslabmc,172.16.0.7/24', 'vlslabmc,172.16.0.10/24', 'vlslabmc,172.16.0.9/24', 'vlslabmc,172.16.0.8/24', 'vlslabmc,172.16.0.2/24', 'vlslabmc,172.16.0.14/24']
      
      largestIP = max(ip_list, key=lambda i: int(i.split('/')[0].split('.')[-1]))
      

      【讨论】:

      • 因为我是 n00b 并且如前所述,我不仅尝试制作 POC,还尝试学习 python,因此我避免使用 max。不过这很好,我会在下一次修订中考虑它。目前刚刚开始工作,我将在 v2 中对其进行一些简化。再次感谢。
      【解决方案3】:

      代码非常复杂(远远超出所需),但错误是ipList 被字符串填充,然后将其元素与整数进行比较。

      这在 Python 2 中是一个无声的问题来源(当比较不同的类型而不是错误时,您会得到一个荒谬但稳定的 True/False 结果),而在 Python 3 中它变成了一个错误。

      在我看来,一个更简单的实现是:

      return max(int(x.split(",")[1].split("/")[0].split(".")[-1])
                 for x in taglist)
      

      含义:

      • split(",")[1] 表示逗号后的部分
      • split("/")[0]参加斜线前的部分
      • split(".")[-1]取IP地址的最后一部分
      • int(...) 转换为整数
      • max(... for x in taglist 为所有元素执行此操作并保持最大值

      或使用正则表达式

      return max(int(re.match(".*?([0-9]+)/", x).group(1))
                 for x in taglist)
      

      【讨论】:

      • 逻辑似乎不错。如果要打印列表中元素的完全匹配。 c = max(int(re.match(".*?([0-9]+)/", x).group(1)) for x in taglist) print "".join(taglist[i] for i in range(len(taglist)) if str(c) in re.split(r'[./]+', taglist[i])[-2])
      • @6502 我只是在乞求编码,所以我把那个复杂的东西用它做了很多简单的,因此很复杂。我认为您的版本更简单,但我还不太精通正则表达式。当我在 POC 后再次查看所有代码时,我可能会这样做。谢谢
      【解决方案4】:

      虽然其他人已经为你提供了一些替代方法来找到答案,但如果你想继续使用你的程序,这里有一些解决方法:

      def findLargestIP():
          ipList = []
          for i in tagList:
              #remove all the spacing in the tags
              ec2Tags = i.strip()
              #seperate any multiple tags
              ec2SingleTag = ec2Tags.split(',')
              #find the last octect of the ip address
              fullIPTag = ec2SingleTag[1].split('.')
              #remove the CIDR from ip to get the last octect
              lastIPsTag = fullIPTag[3].split('/')
              lastOctect = lastIPsTag[0]
              ipList.append(int(lastOctect))
          largestIP  = 0
          for latestIP in ipList:
              if latestIP > largestIP:
                  largestIP = latestIP
          return largestIP
      

      这里和你的程序的不同之处在于我:

      • 设置ipList = []
      • 使 ipList 包含整数,而不是字符串
      • 设置largestIP = 0,而不是获取ipList的第一个数字(因为您不应该假设列表已排序)
      • 删除循环以找到第一个循环之外的最大数 [在tagList] - 只是为了消除不必要的迭代

      但是,如果我要完成这项任务,我会尝试使用正则表达式。这是一种方法:

      import re
      def alternativeFindLargestIP():
          ipList = re.findall(r'(?<=\.)\d+(?=/)', ' '.join(tagList))
          ipList = [int(num) for num in ipList]
          return max(ipList)
      

      【讨论】:

      • 因为我只是想以此为契机学习编码,我更喜欢调整自己的排序与最大排序。还在学习 regedit,所以我还不太习惯使用它。所以你在“largetIP = 0”上是对的,这实际上是我的问题。我将在上面添加编辑。谢谢!
      • 查看我的编辑。具体来说,您能向我解释一下为什么会这样吗?我想不通的是The loop stops at the 1st largest integer. in this case that is 16. *I'm not sure why it does but it does 谢谢!
      • 我认为这是因为您实际上是在整数和字符串之间进行比较。虽然,您设置了largestIP = int(ipList[0]) 并在if 语句if int(latestIP) &gt; largestIP: 中将字符串转换为整数,但是当您设置largestIP 时,您只使用latestIP 进行设置,而不是将其转换为整数。因此,您实际上是在将 17 与 '16' 进行比较,17&gt;'16' 将返回 False。它一直工作到找到 16,因为在此之前,您使用的是手动设置的 largestIP。希望这很清楚。如果不是,请告诉我:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-23
      • 2021-05-06
      • 1970-01-01
      相关资源
      最近更新 更多