[英]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.