将列表/元组对打包成两个列表/元组

Bre*_*ixo 152 python tuples list

可能重复:
Python中的转置/解压缩功能

我有一个如下所示的列表:

list = (('1','a'),('2','b'),('3','c'),('4','d'))
Run Code Online (Sandbox Code Playgroud)

我想将列表分成2个列表.

list1 = ('1','2','3','4')
list2 = ('a','b','c','d')
Run Code Online (Sandbox Code Playgroud)

我可以这样做:

list1 = []
list2 = []
for i in list:
   list1.append(i[0])
   list2.append(i[1])
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有更优雅的解决方案.

agf*_*agf 293

>>> source_list = ('1','a'),('2','b'),('3','c'),('4','d')
>>> list1, list2 = zip(*source_list)
>>> list1
('1', '2', '3', '4')
>>> list2
('a', 'b', 'c', 'd')
Run Code Online (Sandbox Code Playgroud)

编辑:注意这zip(*iterable)是它自己的逆:

>>> list(source_list) == zip(*zip(*source_list))
True
Run Code Online (Sandbox Code Playgroud)

解压缩到两个列表时,会变为:

>>> list1, list2 = zip(*source_list)
>>> list(source_list) == zip(list1, list2)
True
Run Code Online (Sandbox Code Playgroud)

由rockportrocker建议的加法.

  • 我想指出`zip(*list_of_pairs)`的结果不是一对`list`而是`tuple`.在某些情况下,差异可能很重要(例如附加到它).所以示例中的`list1`和`list2`应该是`tuple1`和`tuple2`. (14认同)
  • 对于OP,如果您不了解"splat"运算符,那么http://stackoverflow.com/questions/5239856/foggy-on-asterisk-in-python会很有帮助. (5认同)
  • 这一切都很好,直到你得到一个长度为零的“source_list”。然后你会得到一个错误,而不是像你期望的那样有 2 个空列表。 (3认同)

S.L*_*ott 24

list1= ( x[0] for x in source_list )
list2= ( x[1] for x in source_list )
Run Code Online (Sandbox Code Playgroud)

  • @naeg,这是一个完全正确的pythonic表达式.你甚至可以争论训练较少的程序员这是一个比使用相当模糊的`zip(*...)`语法更好的解决方案. (12认同)
  • 如果你需要实际的`list`s你可以索引,你应该使用方括号`[]`而不是括号来使它们成为列表推导而不是生成器表达式. (2认同)
  • -1,zip()的解决方案更pythonic,并没有两个for循环 (2认同)
  • @KillianDS:嗯,我不认为 zip() 函数或参数的解包是复杂或模糊的?由于 zip-answer 有更多的赞成票,我想其他人也有同样的想法。 (2认同)
  • 它取决于原始列表中元组的长度。如果未知或大于2,则zip(*)更好,否则,这里的解决方案也很好。 (2认同)
  • @sachinruk zip 并不更快。带有附加的循环并不等同于理解表达式。列表理解版本更快。https://i.stack.imgur.com/cJVIX.png (2认同)