简体   繁体   English

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

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

Assuming I have a colection of lists of the same size (same number of elements), where the elements are single elements (strings, numbers) or tuples:假设我有一组相同大小(相同数量的元素)的列表,其中元素是单个元素(字符串、数字)或元组:

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

I would like a way of combining whatever two lists (ideally whatever number of lists) in a way that the result is a list of tuples我想要一种以结果是元组列表的方式组合任何两个列表(最好是任何数量的列表)的方法

# 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)))

Desired result:期望的结果:

pseudo code:伪代码:

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')]

basically the method would get the elements of the input lists treat them as tuples (even if being of only one element) and add up all the values of the tuples of the corresponding same position.基本上,该方法会获取输入列表的元素,将它们视为元组(即使只有一个元素),并将相应相同 position 的元组的所有值相加。

Just flatten the output of zip, as below:将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 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']]

Conversion to a tuple wrt.转换为元组 wrt。 string is cumbersome in python, you have to do it like this: python中的字符串比较繁琐,你必须这样做:

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

Once this is done, the rest is easy:一旦完成,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')]

Another short approach using itertools.chain method:另一种使用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