我有一个由2个元素的元组列表,我想将它们转换成2个列表,其中第一个列表包含每个元组中的第一个元素,第二个列表包含第二个元素。
例如:
original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
# and I want to become...
result = (['a', 'b', 'c', 'd'], [1, 2, 3, 4])
有没有内置函数可以做到这一点?
由于它返回元组(并且可能使用大量内存),对我来说,zip(*zipped)
技巧似乎更聪明而不是有用。
这里有一个函数,实际上会给你 zip 的反转。
def unzip(zipped):
"""Inverse of built-in zip function.
Args:
zipped: a list of tuples
Returns:
a tuple of lists
Example:
a = [1, 2, 3]
b = [4, 5, 6]
zipped = list(zip(a, b))
assert zipped == [(1, 4), (2, 5), (3, 6)]
unzipped = unzip(zipped)
assert unzipped == ([1, 2, 3], [4, 5, 6])
"""
unzipped = ()
if len(zipped) == 0:
return unzipped
dim = len(zipped[0])
for i in range(dim):
unzipped = unzipped + ([tup[i] for tup in zipped], )
return unzipped
zip(*seq)
非常有用,但对于非常长的序列可能不太适用,因为它会创建一个要传递的值元组。例如,我一直在使用一个包含超过一百万个条目的坐标系统,并发现直接创建序列要快得多。from collections import deque
seq = ((a1, b1, …), (a2, b2, …), …)
width = len(seq[0])
output = [deque(len(seq))] * width # preallocate memory
for element in seq:
for s, item in zip(output, element):
s.append(item)
但是,根据您想要对结果进行的操作,集合的选择可能会有很大的差异。在我的实际使用情况中,使用集合而不是内部循环,明显比其他方法更快。
另外,正如其他人所指出的那样,如果您正在处理数据集,可能更好地使用Numpy或Pandas集合。
# data
a = ('a', 'b', 'c', 'd')
b = (1, 2, 3, 4)
# forward
zipped = zip(a, b) # [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
# reverse
a_, b_ = zip(*zipped)
# verify
assert a == a_
assert b == b_
original = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
list(zip(*original))
# [('a', 'b', 'c', 'd'), (1, 2, 3, 4)]
d=dict(original)
后跟d.keys()
和d.values()
可能很方便。 - djvg