【问题标题】:Pythonic way to iterate over a shifted list of tuples迭代元组移位列表的 Pythonic 方法
【发布时间】:2017-12-16 19:31:51
【问题描述】:

给定一个列表L = [('a',3),('b',4),('c',14),('d',10)], 所需的输出是元组中的第一项和下一个元组中的第二项,例如:

a 4
b 14
c 10

直截了当但不符合标准的方式

for i in range(len(L)-1):
    print(L[i][0], L[i+1][1])


或者,这就是我想出的:

for (a0,a1),(b0,b1) in zip(L,L[1:]):
    print(a0,b1)

但这似乎很浪费。有标准的方法吗?

【问题讨论】:

  • 这两种方法都很好,而我(个人)发现后者使用zip 更具可读性和可理解性。这并没有什么浪费,特别是因为zip 在 Python 3 中是惰性的。
  • 我唯一要改变的是使用itertools.islice(L, 1, None) 而不是L[1:]

标签: python python-3.x loops iteration


【解决方案1】:

我个人认为这两个选项都很好 可以提取项目并加入它们:

pairs = zip(map(itemgetter(0), L), map(itemgetter(1), L[1:]))
# [('a', 4), ('b', 14), ('c', 10)]

【讨论】:

    【解决方案2】:

    为了改进您的zip 示例(这已经很好),您可以使用itertools.islice 来避免创建初始列表的切片副本。在python 3中,下面的代码只生成值,过程中没有创建临时列表。

    import itertools
    
    L = [('a',3),('b',4),('c',14),('d',10)]
    
    
    for (a0,_),(_,b1) in zip(L,itertools.islice(L,1,None)):
        print(a0,b1)
    

    【讨论】:

    • 刚刚在大型列表上测试了性能,似乎也快了大约 15%。谢谢!
    • 非常值得islice 的努力。感谢您的接受。
    • 无论你是谁,都感谢你的反对,这是由 1) 解释代码 2) 性能代码 3) 接受的答案
    【解决方案3】:

    pythonic 方法是使用生成器表达式。

    你可以这样写:

    for newTuple in ((L[i][0], L[i+1][1]) for i in range(len(L)-1)):
      print(newTuple)
    

    它看起来像一个列表理解,但迭代器生成器不会创建完整的列表,只会产生一个元组一个元组,因此它不会为列表的完整副本占用额外的内存。

    【讨论】:

    • 一个可爱的作品,确实,Agata
    【解决方案4】:

    我会在两个生成器表达式的帮助下拆分第一个和第二个项目,使用 islice 删除一个项目并将两个流再次压缩在一起。

    first_items = (a for a, _ in L)
    second_items = (b for _, b in L)
    result = zip(first_items, islice(second_items, 1, None))
    
    print(list(result))
    # [('a', 4), ('b', 14), ('c', 10)]
    

    【讨论】:

      猜你喜欢
      • 2012-01-30
      • 2022-08-18
      • 2020-01-13
      • 1970-01-01
      • 2010-11-21
      • 2010-09-30
      相关资源
      最近更新 更多