【问题标题】:How to find an object which contains a specific string and a number which is the highest number?如何找到包含特定字符串和最大数字的对象?
【发布时间】:2018-05-20 08:28:24
【问题描述】:

我是 Python 的初学者,我正在尝试使用 boto (CloudFormation) 列出最新创建的包含字符串的堆栈。

import boto3
client = boto3.client('cloudformation')
stacks = client.list_stacks(
    StackStatusFilter=[
        'CREATE_COMPLETE'
    ]
)

for st in stacks["StackSummaries"]:
    print(st)

这是我运行命令得到的输出的一部分:

{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Dev-31/4d501360-d521-11e7-9aff-50a68a0bca9a', u'StackName': 'Company-Dev-31', u'CreationTime': datetime.datetime(2017, 11, 29, 16, 21, 6, 636000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines @ Oregon (us-west-2)'}
{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Dev-30/4d501360-c231-11e7-8aca-50a68a0bca9a', u'StackName': 'Company-Dev-30', u'CreationTime': datetime.datetime(2017, 11, 29, 16, 21, 6, 644000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines @ Oregon (us-west-2)'}
{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Stg-22/bc2b6c10-d41a-11e7-b1ab-50d5ca789eae', u'StackName': 'Company-Stg-22', u'CreationTime': datetime.datetime(2017, 11, 28, 9, 1, 34, 985000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines @ Oregon (us-west-2)'}
{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Prod-US-API-64/0e85cc00-9602-11e7-8c08-50d5ca0184d2', u'StackName': 'Company-Prod-US-API-64', u'CreationTime': datetime.datetime(2017, 9, 10, 8, 28, 43, 598000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines'}
{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Prod-US-API-63/1ba257c0-9600-11e7-821f-503f20f2ad4a', u'StackName': 'Company-Prod-US-API-63', u'CreationTime': datetime.datetime(2017, 9, 10, 8, 14, 46, 602000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines'}
{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Prod-US-API-61/9252a9d0-2ace-11e7-8eea-503ac9ec2461', u'StackName': 'Company-Prod-US-API-61', u'CreationTime': datetime.datetime(2017, 4, 26, 22, 20, 36, 473000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines'}
{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Prod-US-API-60/1ba83440-2acd-11e7-a0c3-503a90a9c435', u'StackName': 'Company-Prod-US-API-60', u'CreationTime': datetime.datetime(2017, 4, 26, 22, 10, 7, 890000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines'}

好像输出已经按照最新的对象排序了。

我想解析包含单词“Dev”的堆栈的名称,并且在同一环境(Dev)的其余堆栈中编号最高的,在本例中为“Company-Dev-31 ”。

如何实现?

【问题讨论】:

  • print 之前添加if 'dev' in st['StackName'].lower(): ?
  • 谢谢!请创建一个答案。

标签: python amazon-cloudformation boto3


【解决方案1】:

要添加到 Martin 的答案,您可以从每个包含“Dev”的条目中获取数字,然后使用列表推导检索具有最高数字的条目:

numlist = []

for item in st:
    if 'Dev' in item['StackName']:
        num = int(item['StackName'].split('Dev-')[1])
        numlist.append(num)

result = [i for i in st if ('Dev-%s' % max(numlist)) in i['StackName']]

print(result)

给予:

[{u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Dev-31/4d501360-d521-11e7-9aff-50a68a0bca9a', u'StackName': 'Company-Dev-31', u'CreationTime': datetime.datetime(2017, 11, 29, 16, 21, 6, 636000, tzinfo=tzutc()), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines @ Oregon (us-west-2)'}]

【讨论】:

    【解决方案2】:

    意大利,

    首先使用名称中包含 Dev 的堆栈创建一个子列表,然后使用 Dev 编号作为键对结果列表进行排序。

    # make a list of stacks with Dev in stack ID
    sublist = [ s for s in stacks if 'Dev' in s['StackId'] ]
    
    # Extract a number from stack ID
    REGEX = re.compile("Dev-([0-9]+)")
    def extractNum(stack):
        match = REGEX.search(stack['StackId'])
        if match:
            return int(match.group(1))
        else:
            return None
    
    # Sort the stack list in descending order
    sublist.sort(key=extractNum, reverse=True)
    print(sublist[0])
    

    如果您愿意,可以使用内置函数和 lambda 将其压缩为“单线”。

    REGEX = re.compile("Dev-([0-9]+)")
    sublist = sorted(filter(lambda s: 'Dev' in s['StackId'], 
                            stacks),
        key = lambda s: int(REGEX.search(s['StackId']).group(1)),
        reverse = True
        );
    

    filter 生成一个迭代器,它只包含stacks 中符合条件的那些元素

    sorted 使用产生排序值的指定函数创建一个排序列表。

    【讨论】:

      【解决方案3】:

      您可以使用in 测试是否存在某些字符,如下所示:

      import boto3
      client = boto3.client('cloudformation')
      stacks = client.list_stacks(
          StackStatusFilter=[
              'CREATE_COMPLETE'
          ]
      )
      
      for st in stacks["StackSummaries"]:
          if 'dev' in st['StackName'].lower():
              print(st)
      

      这会给你:

      {u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Dev-31/4d501360-d521-11e7-9aff-50a68a0bca9a', u'StackName': 'Company-Dev-31', u'CreationTime': datetime.datetime(2017, 11, 29, 16, 21, 6, 636000), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines @ Oregon (us-west-2)'}
      {u'StackId': 'arn:aws:cloudformation:us-west-2:AWSACCOUNTID:stack/Company-Dev-30/4d501360-c231-11e7-8aca-50a68a0bca9a', u'StackName': 'Company-Dev-30', u'CreationTime': datetime.datetime(2017, 11, 29, 16, 21, 6, 644000), u'StackStatus': 'CREATE_COMPLETE', u'TemplateDescription': 'Company - Formation of Server Machines @ Oregon (us-west-2)'}
      

      将第一个转换为小写具有使测试大小写不敏感的效果,因此Devdev 将匹配。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 2014-06-07
        • 1970-01-01
        相关资源
        最近更新 更多