如果条件为真,则创建具有相邻列表元素的元组列表

时间:2016-07-07 16:57:50

标签: python list python-3.x tuples list-comprehension

我正在尝试创建一个元组列表,其中元组内容是数字9和列表中的数字前面的数字。

输入列表:

myList = [1, 8, 9, 2, 4, 9, 6, 7, 9, 8]

期望输出:

sets = [(8, 9), (4, 9), (7, 9)]

代码:

sets = [list(zip(myList[i:i], myList[-1:])) for i in myList if i==9]

当前结果:

[[], [], []]

6 个答案:

答案 0 :(得分:39)

更清洁的Pythonic方法:

>>> [(x,y) for x,y in zip(myList, myList[1:]) if y == 9]
[(8, 9), (4, 9), (7, 9)]

上面的代码是什么:

  • zip(some_list, some_list[1:])会生成相邻元素对的列表。
  • 现在使用该元组,过滤第二个元素等于9的条件。你完成了:)

答案 1 :(得分:17)

您的部分问题是myList[i:i]将始终返回一个空列表。切片的结尾是独占的,因此当您执行a_list[0:0]时,您尝试在索引0和索引0之间采用存在的<{1}}元素。 / p>

您已经走上了正确的轨道,但是您想要自己压缩列表。

a_list

答案 2 :(得分:7)

你非常接近,如果你刚刚开始,我会告诉你一种可能更直观的替代方式:

sets = [(myList[i-1], myList[i]) for i in range(len(myList)) if myList[i] == 9]

获取列表长度范围内的索引,如果位置i的值等于9,则抓取相邻元素。

结果是:

sets
[(8, 9), (4, 9), (7, 9)]

效率低于其他方法但我决定取消删除它以向您展示不同的方法。您可以使用enumerate()来改善速度:

sets = [(myList[i-1], j) for i, j in enumerate(myList) if j == 9]

请注意myList[0] = 9 的边缘情况下 没有zip的理解行为zip理解的行为不同

具体来说,如果myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8]则:

[(myList[i-1], myList[i]) for i in range(len(myList)) if myList[i] == 9]
# results in: [(8, 9), (8, 9), (4, 9), (7, 9)]

,同时:

[(x, y) for x, y in zip(myList, myList[1:]) if y==9]
# results in: [(8, 9), (4, 9), (7, 9)]

由您来决定哪一个符合您的标准,我只是指出它们在所有情况下的行为都不相同。

答案 3 :(得分:5)

您也可以通过创建迭代器而不切片来完成:

l = myList = [1,8,9,2,4,9,6,7,9,8]

it1, it2 = iter(l), iter(l)
# consume first element from it2 -> leaving 8,9,2,4,9,6,7,9,8
next(it2, "")
# then pair up, (1,8), (8,9) ...
print([(i, j) for i,j in zip(it1, it2) if j == 9])

或使用pairwise recipe创建对

from itertools import tee, izip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

如果使用python3,只需导入 tee 并使用常规 zip

答案 4 :(得分:5)

没有人添加功能方法,这真是令人惊讶。

另一个替代答案是使用filter。这个内置函数返回一个迭代器(Python2中的列表),它包含列表中为特定函数返回True的所有元素

>>> myList = [1,8,9,2,4,9,6,7,9,8]
>>> list(filter(lambda x:x[1]==9,zip(myList, myList[1:])))
[(8, 9), (4, 9), (7, 9)]

需要注意的是list call is needed only in python3+。功能方法和列表推导之间的区别在detail in this post中讨论。

答案 5 :(得分:1)

我的解决方案类似于Jim的高级零指数检查

myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8]

[(myList[i-1], x) for i, x in enumerate(myList) if x==9 and i!=0]

# [(8, 9), (4, 9), (7, 9)]