Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过组合相邻元素并缩短元素长度来转换元组列表_Python_Python 2.7 - Fatal编程技术网

Python 通过组合相邻元素并缩短元素长度来转换元组列表

Python 通过组合相邻元素并缩短元素长度来转换元组列表,python,python-2.7,Python,Python 2.7,我有一个元组列表,长度为偶数x: 我希望创建一个新的元组列表,如下所示: [(a1,a2,b1,b2),(c1,c2,d1,d2),(e1,e2,f1,f2), ... ,((x-1)1,(x-1)2,x1,x2)] 如您所见,子列表的所有第三和第四个元素都已消失,相邻的子列表已合并 我可以用很少的循环来完成它,但我正在寻找优雅的Python方式来完成它。并生成新的元组: [tups[i][:2] + tups[i + 1][:2] for i in xrange(0, len(tups)

我有一个元组列表,长度为偶数x:

我希望创建一个新的元组列表,如下所示:

[(a1,a2,b1,b2),(c1,c2,d1,d2),(e1,e2,f1,f2), ... ,((x-1)1,(x-1)2,x1,x2)]  
如您所见,子列表的所有第三和第四个元素都已消失,相邻的子列表已合并

我可以用很少的循环来完成它,但我正在寻找优雅的Python方式来完成它。

并生成新的元组:

[tups[i][:2] + tups[i + 1][:2] for i in xrange(0, len(tups), 2)]
其中tups是您的输入列表;如果您使用的是Python 3,请使用range

如果tups是一个iterable,而不是一个序列,那么如果您不能使用索引进行快速访问,那么您还可以使用根据您的用例调整的itertools-grouper配方,并适应于Python 2和3:

try:
    # Python 2
    from future_builtins import zip
except ImportError:
    pass  # Python 3

def grouper(iterable, n):
    args = [iter(iterable)] * n
    return zip(*args)

[t1[:2] + t2[:2] for t1, t2 in grouper(tups, 2)]
但如果tups是一个列表,这就有点过分了

演示:

即便如此,石斑鱼选项还是更快的选择,这让我有点吃惊:

In [1]: tups = [('a', 'a', 'a', 'a')] * 1000

In [2]: from future_builtins import zip

In [3]: def grouper(iterable, n):
   ...:         args = [iter(iterable)] * n
   ...:         return zip(*args)
   ...: 

In [4]: %timeit [tups[i][:2] + tups[i + 1][:2] for i in xrange(0, len(tups), 2)]
10000 loops, best of 3: 112 µs per loop

In [5]: %timeit [t1[:2] + t2[:2] for t1, t2 in grouper(tups, 2)]
10000 loops, best of 3: 90.6 µs per loop
并生成新的元组:

[tups[i][:2] + tups[i + 1][:2] for i in xrange(0, len(tups), 2)]
其中tups是您的输入列表;如果您使用的是Python 3,请使用range

如果tups是一个iterable,而不是一个序列,那么如果您不能使用索引进行快速访问,那么您还可以使用根据您的用例调整的itertools-grouper配方,并适应于Python 2和3:

try:
    # Python 2
    from future_builtins import zip
except ImportError:
    pass  # Python 3

def grouper(iterable, n):
    args = [iter(iterable)] * n
    return zip(*args)

[t1[:2] + t2[:2] for t1, t2 in grouper(tups, 2)]
但如果tups是一个列表,这就有点过分了

演示:

即便如此,石斑鱼选项还是更快的选择,这让我有点吃惊:

In [1]: tups = [('a', 'a', 'a', 'a')] * 1000

In [2]: from future_builtins import zip

In [3]: def grouper(iterable, n):
   ...:         args = [iter(iterable)] * n
   ...:         return zip(*args)
   ...: 

In [4]: %timeit [tups[i][:2] + tups[i + 1][:2] for i in xrange(0, len(tups), 2)]
10000 loops, best of 3: 112 µs per loop

In [5]: %timeit [t1[:2] + t2[:2] for t1, t2 in grouper(tups, 2)]
10000 loops, best of 3: 90.6 µs per loop

我思考了什么是Pythonic方法的问题,并得出结论,如果不需要序列,那么接受任何迭代器都是Pythonic方法。从这个意义上讲,Martijn的xrange方法并不是最具python风格的,事实上,Martijn的grouper方法也是如此

result = [ i[:2] + j[:2] for i, j in izip(*[iter(l)] * 2) ]    
是最具python风格的,因为它接受任何类型的iterable

[iterl]*2在两个元素中使用相同的迭代器生成一个2大小的列表。虽然我以前不这么认为,但这比我尝试使用上面的next要快的原因是,调用next代价高昂。相对于内联运算符的使用和元组的构造,所有函数调用和属性/名称解析在CPython上都很慢

这是一个显而易见的快速解决方案,我发现最具python风格的严格列表:

l = [('a1', 'a2', 'a3', 'a4'), ('b1', 'b2', 'b3', 'b4'), ('c1', 'c2', 'c3', 'c4'), ('d1', 'd2', 'd3', 'd4')]
y = [ i[:2] + j[:2] for i, j in zip(l[::2], l[1::2]) ]
print y
哪张照片

[('a1', 'a2', 'b1', 'b2'), ('c1', 'c2', 'd1', 'd2')]
但是,这并不是最有效的,因为zip和切片将在Python 2上创建临时列表,因此为了加快速度,可以将itertools.izip与islice一起使用,以生成一个解决方案

但是,实际上可以在这里滥用迭代器来生成非常高效的代码,尽管不是非常python式的

i = iter(l)
n = i.next
result = [ j[:2] + n()[:2] for j in i ]
print result
印刷品

[('a1', 'a2', 'b1', 'b2'), ('c1', 'c2', 'd1', 'd2')]

列表理解中的for隐式调用迭代器i上的next,并将结果分配给j;在列表理解体中,我们显式地推进相同的迭代器以获得下一个元组。然后,通过元组切片,我们将偶数元组的前两个元素从0开始,并将下一个元组的前两个元素连接到它。但是,如果原始列表中的元素数量不是偶数,则此代码将导致StopIteration异常,这与slice'n'zip解决方案不同,slice'n'zip解决方案只是默默地丢弃最后一个奇数元组。

我思考了什么是Python方式的问题,并得出结论,如果不需要序列,那么接受任何迭代器都将是Pythonic迭代器。从这个意义上讲,Martijn的xrange方法并不是最具python风格的,事实上,Martijn的grouper方法也是如此

result = [ i[:2] + j[:2] for i, j in izip(*[iter(l)] * 2) ]    
是最具python风格的,因为它接受任何类型的iterable

[iterl]*2在两个元素中使用相同的迭代器生成一个2大小的列表。虽然我以前不这么认为,但这比我尝试使用上面的next要快的原因是,调用next代价高昂。相对于内联运算符的使用和元组的构造,所有函数调用和属性/名称解析在CPython上都很慢

这是一个显而易见的快速解决方案,我发现最具python风格的严格列表:

l = [('a1', 'a2', 'a3', 'a4'), ('b1', 'b2', 'b3', 'b4'), ('c1', 'c2', 'c3', 'c4'), ('d1', 'd2', 'd3', 'd4')]
y = [ i[:2] + j[:2] for i, j in zip(l[::2], l[1::2]) ]
print y
哪张照片

[('a1', 'a2', 'b1', 'b2'), ('c1', 'c2', 'd1', 'd2')]
但是,这并不是最有效的,因为zip和切片将在Python 2上创建临时列表,因此为了加快速度,可以将itertools.izip与islice一起使用,以生成一个解决方案

但是,实际上可以在这里滥用迭代器来生成非常高效的代码,尽管不是非常python式的

i = iter(l)
n = i.next
result = [ j[:2] + n()[:2] for j in i ]
print result
印刷品

[('a1', 'a2', 'b1', 'b2'), ('c1', 'c2', 'd1', 'd2')]

列表理解中的for隐式调用迭代器i上的next,并将结果分配给j;在列表理解体中,我们显式地推进相同的迭代器以获得下一个元组。然后,通过元组切片,我们将偶数元组的前两个元素从0开始,并将下一个元组的前两个元素连接到它。但是,如果原始列表中的元素数量不是偶数,则此代码将导致StopIteration异常,这与slice'n'zip解决方案不同,后者只是默默地丢弃最后一个奇数元组。

我不喜欢xrange中的for I…lentups。。。。我宁愿在ziptups[::2]中使用类似于tup1、tup2的东西,tups[1::2]@Kevin:这会创建新的列表对象。然后使用itertools.islice。@Kevin:你也可以在其中使用itertools石斑鱼配方
案例请参见我的答案中链接到的链接问题。但是如果输入是一个序列,那么xrange选项也同样快。如果输入是可编辑的,那么itertools是很棒的。我不喜欢xrange中的for I…lentups。。。。我宁愿在ziptups[::2]中使用类似于tup1、tup2的东西,tups[1::2]@Kevin:这会创建新的列表对象。然后使用itertools.islice。@Kevin:在这种情况下,你也可以使用itertools石斑鱼配方。请参见我的答案中链接到的链接问题。但是如果输入是一个序列,那么xrange选项也同样快。如果输入是可编辑的,那么itertools就太棒了。你有没有自己尝试过什么?[a3、a4、b3、b4,…]发生了什么事?我认为这个问题现在已经足够清楚了,三个答案似乎都理解正确,可以重新打开。@Trilarion,我投票决定结束,因为它太宽泛了,OP没有提供任何代码来显示任何努力也没有帮助。你有没有自己尝试过什么?[a3,a4,b3,b4,…]发生了什么事?我认为这个问题现在已经足够清楚了,三个答案似乎都理解正确,可以重新打开。@Trilarion,我投票决定关闭它,因为它太宽泛了,而且OP没有提供显示任何努力的代码这一事实也没有帮助。必须注意的是,在Python2中,这会创建2个新的列表对象;两个切片和zip返回值,并再次丢弃所有三个。这并没有它可能的那么有效。@AnttiHaapala可能是因为它只是一个代码answer@DarrickHerwehe:hrm,但发布后有点刺耳。必须注意的是,在Python 2中,这会创建2个新的列表对象;两个切片和zip返回值,并再次丢弃所有三个。这并没有它可能的那么有效。@AnttiHaapala可能是因为它只是一个代码answer@DarrickHerwehe:hrm,但发布后有点刺耳。