Extended tuple unpacking in Python 2

前端 未结 5 1254
时光取名叫无心
时光取名叫无心 2020-11-27 21:14

Is it possible to simulate extended tuple unpacking in Python 2?

Specifically, I have a for loop:

for a, b, c in mylist:

which work

相关标签:
5条回答
  • 2020-11-27 21:14

    You can't do that directly, but it isn't terribly difficult to write a utility function to do this:

    >>> def unpack_list(a, b, c, *d):
    ...   return a, b, c, d
    ... 
    >>> unpack_list(*range(100))
    (0, 1, 2, (3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99))
    

    You could apply it to your for loop like this:

    for sub_list in mylist:
        a, b, c, d = unpack_list(*sub_list)
    
    0 讨论(0)
  • 2020-11-27 21:21

    You can write a very basic function that has exactly the same functionality as the python3 extended unpack. Slightly verbose for legibility. Note that 'rest' is the position of where the asterisk would be (starting with first position 1, not 0)

    def extended_unpack(seq, n=3, rest=3):
        res = []; cur = 0
        lrest = len(seq) - (n - 1)    # length of 'rest' of sequence
        while (cur < len(seq)):
            if (cur != rest):         # if I am not where I should leave the rest
                res.append(seq[cur])  # append current element to result
            else:                     # if I need to leave the rest
                res.append(seq[cur : lrest + cur]) # leave the rest
                cur = cur + lrest - 1 # current index movded to include rest
            cur = cur + 1             # update current position
         return(res)
    
    0 讨论(0)
  • 2020-11-27 21:27

    For the heck of it, generalized to unpack any number of elements:

    lst = [(1, 2, 3, 4, 5), (6, 7, 8), (9, 10, 11, 12)]
    
    def unpack(seq, n=2):
        for row in seq:
            yield [e for e in row[:n]] + [row[n:]]
    
    for a, rest in unpack(lst, 1):
        pass
    
    for a, b, rest in unpack(lst, 2):
        pass
    
    for a, b, c, rest in unpack(lst, 3):
        pass
    
    0 讨论(0)
  • 2020-11-27 21:39

    You could define a wrapper function that converts your list to a four tuple. For example:

    def wrapper(thelist):
        for item in thelist:
            yield(item[0], item[1], item[2], item[3:])
    
    mylist = [(1,2,3,4), (5,6,7,8)]
    
    for a, b, c, d in wrapper(mylist):
        print a, b, c, d
    

    The code prints:

    1 2 3 (4,)
    5 6 7 (8,)
    
    0 讨论(0)
  • 2020-11-27 21:39

    Python 3 solution for those that landed here via an web search:

    You can use itertools.zip_longest, like this:

    from itertools import zip_longest
    
    max_params = 4
    
    lst = [1, 2, 3, 4]
    a, b, c, d = next(zip(*zip_longest(lst, range(max_params))))
    print(f'{a}, {b}, {c}, {d}') # 1, 2, 3, 4
    
    lst = [1, 2, 3]
    a, b, c, d = next(zip(*zip_longest(lst, range(max_params))))
    print(f'{a}, {b}, {c}, {d}') # 1, 2, 3, None
    

    For Python 2.x you can follow this answer.

    0 讨论(0)
提交回复
热议问题