实现以下目标的Python方法是什么?

# Original lists:

list_a = [1, 2, 3, 4]
list_b = [5, 6, 7, 8]

# List of tuples from 'list_a' and 'list_b':

list_c = [(1,5), (2,6), (3,7), (4,8)]


list_c的每个成员都是一个元组,其第一个成员来自list_a,第二个成员来自list_b。 />

#1 楼

在Python 2中:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> zip(list_a, list_b)
[(1, 5), (2, 6), (3, 7), (4, 8)]


在Python 3中:

>>> list_a = [1, 2, 3, 4]
>>> list_b = [5, 6, 7, 8]
>>> list(zip(list_a, list_b))
[(1, 5), (2, 6), (3, 7), (4, 8)]


评论


您必须知道zip功能在最短列表的末尾停止,而列表可能并不总是您想要的。 itertools模块定义了一个zip_longest()方法,该方法在最长列表的末尾停止,用您提供的参数填充缺失值。

– Adrien Plisson
10 Mar 9 '10 at 10:05

@Adrien:为您的适用评论打气。对于Python 2.x,请使用s / zip_longest()/ izip_longest()。在Python 3.x中重命名为zip_longest()。

–mechanical_meat
2011年7月10日19:13



我可以使用zip命令创建[(1,5),(1,6),(1,7),(1,8),(2,5),(2,6)等吗?

–莫娜·贾拉勒(Mona Jalal)
16年5月30日在4:39



@MonaJalal:不,这不是配对,而是创建列表的产品。 itertools.product()可以做到这一点。

–马丁·彼得斯(Martijn Pieters)♦
16年8月9日在16:12

注意,至少在python3.6中zip不返回列表。所以你需要用list(zip(list_a,list_b))代替

– Supeme
18-10-2在15:45

#2 楼

在python 3.0中,zip返回一个zip对象。您可以通过调用list(zip(a, b))获得列表。

评论


这可能是微不足道的,但请注意,直接在for循环中使用它会为您提供一个生成器,该生成器在使用一次后将被耗尽。如果要更频繁地使用它,请保存到变量中

– Hakaishin
18-09-25在13:34

#3 楼

您可以使用map lambda

a = [2,3,4]
b = [5,6,7]
c = map(lambda x,y:(x,y),a,b)


如果原始列表的长度不匹配,这也将起作用

评论


为什么要使用lambda?地图(无,a,b)

–坎宁安(Padraic Cunningham)
16年6月8日,0:19

我只能访问python 3.5。

–黑暗骑士
16年7月13日在0:40

如果您使用的是python3,则c不会是列表,它会是一个地图对象,而且如果您使用不同的长度列表并要处理该列表,那么使用lambda的效率将比仅使用zip的效率低很多。 izip_longest / zip_longest

–坎宁安(Padraic Cunningham)
16年8月10日在9:09



当“原始列表的长度不匹配”时,它不起作用。

–安瑟
9月17日晚上8:22

#4 楼

您正在寻找内置的功能zip。

#5 楼

我不确定这是否是pythonic方式,但是如果两个列表具有相同数量的元素,这似乎很简单:

list_a = [1, 2, 3, 4]

list_b = [5, 6, 7, 8]

list_c=[(list_a[i],list_b[i]) for i in range(0,len(list_a))]


#6 楼

我知道这是一个古老的问题,已经得到回答,但是由于某些原因,我仍然想发布此替代解决方案。我知道很容易找出哪个内置函数可以完成您所需的“魔术”,但是知道您可以自己完成此操作也没有什么害处。

>>> list_1 = ['Ace', 'King']
>>> list_2 = ['Spades', 'Clubs', 'Diamonds']
>>> deck = []
>>> for i in range(max((len(list_1),len(list_2)))):
        while True:
            try:
                card = (list_1[i],list_2[i])
            except IndexError:
                if len(list_1)>len(list_2):
                    list_2.append('')
                    card = (list_1[i],list_2[i])
                elif len(list_1)<len(list_2):
                    list_1.append('')
                    card = (list_1[i], list_2[i])
                continue
            deck.append(card)
            break
>>>
>>> #and the result should be:
>>> print deck
>>> [('Ace', 'Spades'), ('King', 'Clubs'), ('', 'Diamonds')]


评论


更改输入列表之一(如果它们的长度不同)不是一个很好的副作用。另外,不需要在if-elif中对card进行两次分配,这就是为什么要继续的原因。 (实际上,如果没有继续操作,则无需更改列表:前面提到的两个分配都应保留,并成为card =(list_1 [i],'')和card =('',list_2 [1]))分别。)

–ᴠɪɴᴄᴇɴᴛ
17年1月7日在15:01



#7 楼

您在问题陈述中显示的输出不是元组而是列表

list_c = [(1,5), (2,6), (3,7), (4,8)]


检查

type(list_c)


考虑到您希望结果作为list_a和list_b中的元组,请执行

tuple(zip(list_a,list_b)) 


评论


从我的角度来看,这似乎是我正在寻找的东西,并且两者(列表和元组)都可以正常工作。因为使用print时,您将看到正确的值(如预期并由@cyborg和@Lodewijk提及),并且与该对象无关,例如:。至少,对我来说,关于map和zip(单独)的解决方案似乎不完整(或太复杂)。

– Wagner_SOFC
17年5月28日在1:40

问题指出,他们想要一个元组列表,而不是一个元组列表。

–高丽
19年6月13日在22:41

#8 楼

一种不使用zip的替代方法:

list_c = [(p1, p2) for idx1, p1 in enumerate(list_a) for idx2, p2 in enumerate(list_b) if idx1==idx2]


如果不仅要获取元组1st与1st,2nd与2nd ...,还要获取2个列表的所有可能组合,可以使用

list_d = [(p1, p2) for p1 in list_a for p2 in list_b]