简体   繁体   English

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

[英]Create a list of tuples with adjacent list elements if a condition is true

I am trying to create a list of tuples where the tuple contents are the number 9 and the number before it in the list. 我正在尝试创建一个元组列表,其中元组内容为数字9 ,列表中的数字为前面的数字。

Input List: 输入清单:

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

Desired Output: 期望的输出:

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

Code: 码:

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

Current Result: 目前的结果:

[[], [], []]

Cleaner Pythonic approach: 更清洁的Pythonic方法:

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

What is the code above doing: 上面的代码是做什么的:

  • zip(some_list, some_list[1:]) would generate a list of pairs of adjacent elements. zip(some_list, some_list[1:])将生成一对相邻元素的列表。
  • Now with that tuple, filter on the condition that the second element is equal to 9 . 现在使用该元组,在第二个元素等于9的条件下进行过滤。 You're done :) 你完成了 :)

Part of your issue is that myList[i:i] will always return an empty list. 您的部分问题是myList[i:i]将始终返回一个空列表。 The end of a slice is exclusive, so when you do a_list[0:0] you're trying to take the elements of a_list that exist between index 0 and index 0. 切片的结尾是独占的,所以当你执行a_list[0:0]你试图获取索引0和索引0 之间存在的a_list元素。

You're on the right track, but you want to zip the list with itself. 你是在正确的轨道上,但你想要自己压缩列表。

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

You were pretty close, I'll show you an alternative way that might be more intuitive if you're just starting out: 你非常接近,如果你刚刚开始,我会告诉你另一种可能更直观的方式:

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

Get the index in the range of the list lenght, and if the value at the position i is equal to 9 , grab the adjacent elements. 获取列表长度范围内的索引,如果位置i值等于9 ,则抓取相邻元素。

The result is: 结果是:

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

This is less efficient than the other approaches but I decided to un-delete it to show you a different way of doing it. 比其他方法效率低,但我决定取消删除它以向您展示不同的方法。 You can make it go a bit faster by using enumerate() instead: 你可以使用enumerate()代替它:

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

Take note that in the edge case where myList[0] = 9 the behavior of the comprehension without zip and the behavior of the comprehension with zip is different . 请注意myList[0] = 9的边缘情况下,没有zip的理解行为和zip的理解行为是不同的

Specifically, if myList = [9, 1, 8, 9, 2, 4, 9, 6, 7, 9, 8] then: 具体来说,如果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)]

while: 而:

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

It is up to you to decide which of these fits your criteria, I'm just pointing out that they don't behave the same in all cases. 由你来决定哪一个符合你的标准,我只是指出它们在所有情况下的表现都不一样。

You can also do it without slicing by creating iterators: 您也可以通过创建迭代器来完成它而不进行切片:

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])

Or use the pairwise recipe to create your pairs 或者使用成对配方来创建配对

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)

If using python3, just import tee and use the regular zip . 如果使用python3,只需导入tee并使用常规zip

It is really surprising that no one has added a functional approach. 令人惊讶的是,没有人添加功能方法。

Another alternative answer is using a filter . 另一个替代答案是使用filter This builtin function returns an iterator (list in Python2) consisting of all the elements present in the list that return True for a particular function 这个内置函数返回一个迭代器(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)]

It is to be noted that the list call is needed only in python3+ . 需要注意的是,只有在python3 +中才需要list调用 The difference between the functional approach and list comprehensions is discussed in detail in this post . 本文详细讨论了功能方法和列表推导之间的区别。

My solution is similar to one of Jim's advanced with zero-index check 我的解决方案类似于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)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM