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

时间:2022-02-13 10:59:55

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:

[[], [], []]

6 个解决方案

#1


39  

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. You're done :)
  • 现在有了这个元组,过滤第二个元素等于9的条件。你做完了:)

#2


17  

Part of your issue is that myList[i:i] will always return an empty list. 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.

你的部分问题是myList [i:i]将始终返回一个空列表。切片的结尾是独占的,所以当你执行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]

#3


7  

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.

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

#4


5  

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。

#5


5  

It is really surprising that no one has added a functional approach.

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

Another alternative answer is using a 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+. The difference between the functional approach and list comprehensions is discussed in detail in this post.

需要注意的是,只有在python3 +中才需要列表调用。本文详细讨论了功能方法和列表推导之间的区别。

#6


1  

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

#1


39  

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. You're done :)
  • 现在有了这个元组,过滤第二个元素等于9的条件。你做完了:)

#2


17  

Part of your issue is that myList[i:i] will always return an empty list. 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.

你的部分问题是myList [i:i]将始终返回一个空列表。切片的结尾是独占的,所以当你执行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]

#3


7  

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.

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

#4


5  

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。

#5


5  

It is really surprising that no one has added a functional approach.

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

Another alternative answer is using a 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+. The difference between the functional approach and list comprehensions is discussed in detail in this post.

需要注意的是,只有在python3 +中才需要列表调用。本文详细讨论了功能方法和列表推导之间的区别。

#6


1  

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