繁体   English   中英

python 将单个元素或元组列表压缩到元组列表中

[英]python ziping lists of single element or tuples into list of tuples

假设我有一组相同大小(相同数量的元素)的列表,其中元素是单个元素(字符串、数字)或元组:

a = ['AA', 'BB', 'CC']
b = [7,8,9]
d = [('TT', 'ZZ'),('UU', 'VV'),('JJ','KK')]
e = [('mm', 'nn'), ('bb', 'vv'), ('uu', 'oo')]

我想要一种以结果是元组列表的方式组合任何两个列表(最好是任何数量的列表)的方法

# none of this works:
print(list(zip(a,b))) # this ONLY works for the case in which a & b have single elements, not tuples
print(list(zip(b,*d)))
print(list(zip(*d,*e)))

期望的结果:

伪代码:

combination of a,b = [('AA', 7), ('BB', 8), ('CC', 9)]
combination of a,d = [('AA','TT', 'ZZ'),('BB', 'UU', 'VV'),('CC','JJ','KK')]
combination of d,e = [('TT', 'ZZ','mm', 'nn'),('UU', 'VV','bb', 'vv'),('JJ','KK','uu', 'oo')]

基本上,该方法会获取输入列表的元素,将它们视为元组(即使只有一个元素),并将相应相同 position 的元组的所有值相加。

将zip的output压平即可,如下:

from collections.abc import Iterable

a = ['AA', 'BB', 'CC']
b = [7, 8, 9]
d = [('TT', 'ZZ'), ('UU', 'VV'), ('JJ', 'KK')]
e = [('mm', 'nn'), ('bb', 'vv'), ('uu', 'oo')]


def flatten(*e):
    for ei in e:
        yield from (ei,) if not (isinstance(ei, Iterable) or isinstance(ei, str)) else ei


print([list(flatten(ei)) for ei in zip(a, b)])
print([list(flatten(ei)) for ei in zip(a, d)])
print([list(flatten(ei)) for ei in zip(d, e)])

Output

[['AA', 7], ['BB', 8], ['CC', 9]]
[['AA', 'TT', 'ZZ'], ['BB', 'UU', 'VV'], ['CC', 'JJ', 'KK']]
[['TT', 'ZZ', 'mm', 'nn'], ['UU', 'VV', 'bb', 'vv'], ['JJ', 'KK', 'uu', 'oo']]

转换为元组 wrt。 python中的字符串比较繁琐,你必须这样做:

def to_tuple(s):
    if isinstance(s, str):
        return s,
    try:
        return tuple(s)
    except TypeError:
        return s,

一旦完成,rest 就很容易了:

a_plus_d = [to_tuple(x) + to_tuple(y)
            for x, y in zip(a, d)]
def foo(x, y):
    x = [x] if not isinstance(x, (tuple, list)) else x
    y = [y] if not isinstance(y, (tuple, list)) else y
    return [el for item in [x, y] for el in item]
    
[tuple(foo(el1, el2)) for el1, el2 in list(zip(a, d))]
# [('AA', 'TT', 'ZZ'), ('BB', 'UU', 'VV'), ('CC', 'JJ', 'KK')]

另一种使用itertools.chain方法的简短方法:

import itertools

def combine_lists(*lists):
    return list(tuple(itertools.chain(*[i if isinstance(i, (list, tuple)) else (i,) for i in items]))
                for items in zip(*lists))

print(combine_lists(a, b, e))  # [('AA', 7, 'mm', 'nn'), ('BB', 8, 'bb', 'vv'), ('CC', 9, 'uu', 'oo')]

暂无
暂无

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

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