简体   繁体   English

如何使用itertools将返回的值从一个函数传递给另一个函数?

[英]How to use itertools to pass the returned values from one function to another?

I have a list being returned as 我有一个列表被返回为

[('10.12.250.29', 'pdx02-he-trial-ansible01', 'us-west-2a', 'vol-e7775a10'), ('10.12.32.22', 'pdx02-cloud-prod-ansible01 Clone ', 'us-west-2b', 'vol-b0607d70'), ('10.12.0.20', 'pdx02-cloud-trial/dev-ansible01', 'us-west-2a', 'vol-b32e5c46'), ('10.12.250.7', 'pdx02-he-prod-ansible01', 'us-west-2a', 'vol-fd94400b'), ('10.12.250.4', 'pdx02-he-dev-ansible01', 'us-west-2a', 'vol-ee6abf18'), ('10.12.32.16', 'pdx02-cloud-prod-ansible', 'us-west-2b', 'vol-ae49adbb'), ('10.121.15.22', 'ansible-classic', 'us-west-2a', 'vol-f893c20d'), ('10.17.15.145', 'pdx01-ms-dev-ansible', 'us-west-2a', 'vol-e2d45515'), ('10.21.32.27', 'fra01-cloud-prod-ansible', 'eu-central-1b', 'vol-5f86f5bd'), ('10.21.250.13', 'fra01-he-trial-ansible01', 'eu-central-1a', 'vol-f9e7d220'), ('10.21.250.27', 'fra01-he-dev-ansible01', 'eu-central-1a', 'vol-f6e3fa2f'), ('10.21.0.9', 'fra01-cloud-dev-ansible01', 'eu-central-1a', 'vol-98104671'), ('10.21.250.5', 'fra01-he-prod-ansible01', 'eu-central-1a', 'vol-809b8259'), ('10.31.250.26', 'sin01-he-dev-ansible01', 'ap-southeast-1a', 'vol-86443940'), ('10.31.250.19', 'sin01-he-prod-ansible01', 'ap-southeast-1a', 'vol-bebcc178'), ('10.31.32.12', 'sin01-cloud-prod-ansible01', 'ap-southeast-1b', 'vol-01409de9'), ('10.31.250.27', 'sin01-he-trial-ansible01', 'ap-southeast-1a', 'vol-f6cdc631'), ('10.31.0.18', 'sin01-cloud-dev-ansible01', 'ap-southeast-1a', 'vol-3c0aac28')]

this is basically: 这基本上是:

<IP_ADDRESS> , <AWS_TAG_NAME> , <REGION> , <VOLUME>

now I passed it to another method where I need to extract each value and store it individually so I used itertools from __main__ : 现在,我将其传递给另一种方法,在该方法中,我需要提取每个值并将其单独存储,因此我使用了来自__main__ itertools

data = list(itertools.chain(*ansible_box_info))
print "-----------------"
print data
#mapping = {i[0]: [i[1], i[2]] for i in data}
print "Now Calling the Snapshot Creater!"
call_snapshot_creater(data)

def call_snapshot_creater(passed_data):
    ip_address = ','.join(list(itertools.chain(*[[j[0] for j in i] for i in data])))
    tags_descrip = list(itertools.chain(*[[j[1] for j in i] for i in data]))
    regions_az = list(itertools.chain(*[[j[2] for j in i] for i in data]))
    volume_id = list(itertools.chain(*[[j[3] for j in i] for i in data]))

This breaks the above list and picks just the first letter of everything , ie the ip_address prints : 这打破了上面的列表,只选择了所有内容的首字母,即ip_address打印:

1,p,u,v,1,p,u,v,1,p,u,v,1,p,u,v,1,p,u,v,1,p,u,v,1,a,u,v,1,p,u,v,1,f,e,v,1,f,e,v,1,f,e,v,1,f,e,v,1,f,e,v,1,s,a,v,1,s,a,v,1,s,a,v,1,s,a,v,1,s,a,v

instead of 10.12.250.29 , 10.12.32.22 .................. and same for others 代替10.12.250.29,10.12.32.22 ..................

how to use the iterators to break this correctly ? 如何使用迭代器正确打破这一点?

I am trying to create snapshots by passing these values to my snapshot creator : 我试图通过将这些值传递给快照创建者来创建快照:

def call_snapshot_creater(passed_data):
    ip_address = ','.join(list(itertools.chain(*[[j[0] for j in i] for i in data])))
    tags_descrip = list(itertools.chain(*[[j[1] for j in i] for i in data]))
    regions_az = list(itertools.chain(*[[j[2] for j in i] for i in data]))
    volume_id = list(itertools.chain(*[[j[3] for j in i] for i in data]))

    regions = ['us-west-2', 'eu-central-1', 'ap-southeast-1']

    for region in regions:
        ec2 = boto3.resource('ec2', region, aws_access_key_id=ACCESS_KEY, aws_secret_access_key=SECRET_KEY, )
        print "Snapshot Creation For Ansible -> ",ip_address," initiated , tag = ", tags_descrip ,"region : ", regions_az
        print "Snapshot will be created with -> Name : ",tags_descrip
        snapshot = ec2.create_snapshot(VolumeId=volume_id, Description=tags_descrip)
        print snapshot.id
        print "Snapshot is being created for Ansible box ", tags_descrip ,"with snapshot id :",snapshot.id
        #slack.chat.post_message(slack_channel,"Creating Snapshot for The volume"+ str(snapshot.id),username='Ansible_box_snapshot_bot')
        snapshot.load()
        while snapshot.state != 'completed':
            print "The Snapshot :", snapshot.id , "for Ansible box named : ", tags_descrip  ,"is currently in :",snapshot.state," state"
            time.sleep(30)
            snapshot.load()
            print snapshot.progress
        else:
            print "Snapshot ",snapshot.id, "for Ansible box ", tags_descrip , "is now Ready!! Final state ->",snapshot.state

with [[j[0] for j in i] for i in data] you are going through the list, and calculate [j[0] for j in i] , where i is the current tuple. 使用[[j[0] for j in i] for i in data]您将遍历该列表,并计算[j[0] for j in i] ,其中i是当前元组。 So you iterate through the tuple, where j is the current string, and you get the first character of that string. 因此,您遍历元组,其中j是当前字符串,并获得该字符串的第一个字符。

What you want however, is only the first item of the tuple. 但是,您想要的只是元组的第一项。 This means that you don't even need itertools.chain : Do it with [i[0] for i in data] . 这意味着您甚至不需要itertools.chain :使用[i[0] for i in data] This gets the first element of each tuple, and yields the expected output. 这将获取每个元组的第一个元素,并产生预期的输出。

So here is the changed code: 因此,这是更改后的代码:

ip_address = ','.join(i[0] for i in data)  # you can use an iterator here
tags_descrip = ','.join(i[1] for i in data)
regions_az = ','.join(i[2] for i in data)
volume_id = ','.join(i[3] for i in data)

This can, however, all be done in one line: 但是,这可以全部一行完成:

ip_address, tags_descrip, regions_az, volume_id = (','.join(j[i] for j in data) for i in range(4))

Another possibility would be following: (Here you only iterate over data once, but it isn't that readable) 另一个可能性如下:(这里您仅对data一次迭代,但是可读性不强)

ip_address, tags_descrip, regions_az, volume_id = map(','.join, zip(*data))

Here is how the second one works (I think the first one is self explanatory): 这是第二个方法的工作原理(我认为第一个是不言而喻的):

You pass following tuples to zip : 您将以下元组传递给zip

IP, ... from the first tuple
IP, ... from the second tuple
   .
   .
   .

So all the different fields are aligned. 因此,所有不同的字段都是对齐的。 zip gives you an iterator, that returns the tuple containing the first items of each list, then a tuple containing the second items, and so on. zip为您提供了一个迭代器,该迭代器返回包含每个列表的第一项的元组,然后返回包含第二项的元组,依此类推。 So if you would call list(zip(*data)) , you would have a list with for entries: All the IP's, and so on. 因此,如果您要调用list(zip(*data)) ,则将具有一个用于输入的列表:所有IP,依此类推。

I would choose the first option over the second one, because the first one is a whole lot more readable, but if you really care for performance (but you wouldn't use Python in this case, I suppose), the second one is the way to go. 我会选择第一个选项而不是第二个选项,因为第一个选项更具可读性,但是如果您确实关心性能(我想在这种情况下您不会使用Python),那么第二个选项是要走的路。

I hope I could help, 我希望我能帮上忙,

CodenameLambda 代号Lambda

You are not using chain and unpacking correctly. 您没有使用chain并正确拆箱 All you are trying to do, can be done with zip and unpacking viz. 您尝试做的所有事情都可以通过zip 和解 zip viz完成。 zip(*...) : zip(*...)

>>> l = [('10.12.250.29', 'pdx02-he-trial-ansible01', 'us-west-2a', 'vol-e7775a10'), ('10.12.32.22', 'pdx02-cloud-prod-ansible01 Clone ', 'us-west-2b', 'vol-b0607d70'), ('10.12.0.20', 'pdx02-cloud-trial/dev-ansible01', 'us-west-2a', 'vol-b32e5c46'), ('10.12.250.7', 'pdx02-he-prod-ansible01', 'us-west-2a', 'vol-fd94400b'), ('10.12.250.4', 'pdx02-he-dev-ansible01', 'us-west-2a', 'vol-ee6abf18'), ('10.12.32.16', 'pdx02-cloud-prod-ansible', 'us-west-2b', 'vol-ae49adbb'), ('10.121.15.22', 'ansible-classic', 'us-west-2a', 'vol-f893c20d'), ('10.17.15.145', 'pdx01-ms-dev-ansible', 'us-west-2a', 'vol-e2d45515')]
>>>
>>> data = zip(*l)
>>>
>>> ip_address = ','.join(next(data))
>>> ip_address
'10.12.250.29,10.12.32.22,10.12.0.20,10.12.250.7,10.12.250.4,10.12.32.16,10.121.15.22,10.17.15.145'
>>>
>>> tags_descrip = ','.join(next(data))
>>> tags_descrip
'pdx02-he-trial-ansible01,pdx02-cloud-prod-ansible01 Clone ,pdx02-cloud-trial/dev-ansible01,pdx02-he-prod-ansible01,pdx02-he-dev-ansible01,pdx02-cloud-prod-ansible,ansible-classic,pdx01-ms-dev-ansible'
>>>
>>> regions_az = ','.join(next(data))
>>> regions_az
'us-west-2a,us-west-2b,us-west-2a,us-west-2a,us-west-2a,us-west-2b,us-west-2a,us-west-2a'
>>>
>>> volume_id = ','.join(next(data))
>>> volume_id
'vol-e7775a10,vol-b0607d70,vol-b32e5c46,vol-fd94400b,vol-ee6abf18,vol-ae49adbb,vol-f893c20d,vol-e2d45515'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM