簡體   English   中英

Python如何檢查for循環中的最后一個元素?

[英]Python how to check if last element in for loop?

給出以下代碼:

...
libera_client = libera_get_client(endpoint=endpoint, access_key=access_key, secret_key=secret_key, region=region)
libera_transfer = s3transfer.create_transfer_manager(libera_transfer_client, transfer_config)
all_segments_uploaded = False
retry_list = []
while not all_segments_uploaded:
    upload = None
    if len(retry_list) > 0:
        for src, dst in [(p[0], p[1]) for p in retry_list]:
            upload = libera_transfer.upload(fileobj=src, bucket=bucket, key=dst,
                                            subscribers=[s3transfer.ProgressCallbackInvoker(progress_func)])
    else:
        for src, dst in [(p[0], p[1]) for p in upload_list]:
            upload = libera_transfer.upload(fileobj=src, bucket=bucket, key=dst,
                                            subscribers=[s3transfer.ProgressCallbackInvoker(progress_func)])
    upload.result()   # This is just to wait for the upload to be finished
    for src, dst in [(p[0], p[1]) for p in enumerate(upload_list)]:
        print(f'HEAD Object validation of upload: {dst}')
        try:
            libera_client.head_object(Bucket=bucket, Key=dst, ChecksumMode='ENABLED')
        except ClientError as e:
            all_segments_uploaded = False
            retry_list.append([src, dst])
            print(f'Integrity check failed with: {e}, Upload will get reinitialized until completion!')
            if len(upload_list[:-1]):
                break
            else:
                continue
        all_segments_uploaded = True

libera_transfer.shutdown()

return libera_transfer

如何正確檢查我是否正在處理 for 循環中的最后一個元素? 一旦達到最后一個元素,我就想打破。

嘗試使用索引號並迭代,迭代到最后一個元素,我認為應該可以

    for i in range(len(upload_list)): # iterate whole list using index value
        src = upload_list[i][0] 
        dst = upload_list[i][1] 
        print(f'HEAD Object validation of upload: {dst}')
        try:
            libera_client.head_object(Bucket=bucket, Key=dst, ChecksumMode='ENABLED')
        except ClientError as e:
            all_segments_uploaded = False
            retry_list.append([src, dst])
            print(f'Integrity check failed with: {e}, Upload will get reinitialized until completion!')
            if (i == len(upload_list)-1): # so you check here, if current index is equal to last index or not
                break
            else:
                continue
        all_segments_uploaded = True

您可以將迭代器保存在列表中,而不是使用 for 循環,然后僅傳遞 len(iterator)-1 數據

data = [(p[0], p[1]) for p in enumerate(upload_list)]
len_data = len(data)

for index, (src, dest) in enumerate(data[:-1])
     # rest of code
# or 

for index, (src, dest) in enumerate(data):
     if index ==len_data-1:
           break
     # rest of code

在您的場景中,您正在使用enumerate並且您希望在for的最后一個元素處break ,以便您可以檢查enumerate返回的索引和upload_list的長度。

enumerate返回indexelement ,以便您可以比較upload_list的索引和長度

for src, dst in [(p[0], p[1]) for p in enumerate(upload_list)]:
        print(src,dst)
        if len(upload_list)-1==src:
            print("last")
            break

你可以直接解包枚舉如下:

for src, dst in enumerate(upload_list):
        print(src,dst)
        if len(upload_list)-1==src:
            print("last")
            break

PS。 一旦迭代器中的所有元素都用完for循環將停止迭代。 如果可能,請說明您對此類手動行為的用例以明確說明。

我的一個朋友提出了縮小列表並用剩余的upload_list填充重試列表的解決方案。 這縮短了代碼並按預期完成了工作:

libera_client = libera_get_client(endpoint=endpoint, access_key=access_key, secret_key=secret_key, region=region)
libera_transfer = s3transfer.create_transfer_manager(libera_transfer_client, transfer_config)
all_segments_uploaded = False
while not all_segments_uploaded:
    retry_list = []
    upload = None

    for src, dst in [(p[0], p[1]) for p in upload_list]:
        upload = libera_transfer.upload(fileobj=src, bucket=bucket, key=dst,
                                        subscribers=[s3transfer.ProgressCallbackInvoker(progress_func)])
    upload.result()
    for src, dst in [(p[0], p[1]) for p in upload_list]:
        print(f'HEAD Object validation of upload: {dst}')
        try:
            libera_client.head_object(Bucket=bucket, Key=dst, ChecksumMode='ENABLED')
        except ClientError as e:
            retry_list.append([src, dst])
            print(f'Integrity check failed with: {e}, Upload will get reinitialized until completion!')
            all_segments_uploaded = False
    if len(retry_list) > 0:
        upload_list = retry_list
    else:
        all_segments_uploaded = True

libera_transfer.shutdown()

return libera_transfer

我不會將此標記為解決方案,因為它並不能真正處理原始問題(獲取列表中的最后一個元素)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM